一、应用程序直接获取数据库连接的缺点

  用户每次请求都需要向数据库获得链接,而数据库创建连接通常需要消耗相对较大的资源,创建时间也较长。假设网站一天10万访问量,数据库服务器就需要创建10万次连接,极大的浪费数据库的资源,并且极易造成数据库服务器内存溢出、拓机。如下图所示:

  

二、使用数据库连接池优化程序性能

2.1、数据库连接池的基本概念

  数据库连接是一种关键的有限的昂贵的资源,这一点在多用户的网页应用程序中体现的尤为突出.对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标.数据库连接池正式针对这个问题提出来的.数据库连接池负责分配,管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。如下图所示:

  

数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中, 这些数据库连接的数量是由最小数据库连接数来设定的.无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量.连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中.

数据库连接池的最小连接数和最大连接数的设置要考虑到以下几个因素:

  1. 最小连接数:是连接池一直保持的数据库连接,所以如果应用程序对数据库连接的使用量不大,将会有大量的数据库连接资源被浪费.
  2. 最大连接数:是连接池能申请的最大连接数,如果数据库连接请求超过次数,后面的数据库连接请求将被加入到等待队列中,这会影响以后的数据库操作
  3. 如果最小连接数与最大连接数相差很大:那么最先连接请求将会获利,之后超过最小连接数量的连接请求等价于建立一个新的数据库连接.不过,这些大于最小连接数的数据库连接在使用完不会马上被释放,他将被放到连接池中等待重复使用或是空间超时后被释放.

2.2 常见的Java连接池

  自定义连接池,DBCP连接池,C3P0连接池,Druid等

2.3举个栗子

假设设置了最小和最大的连接为10,20,那么应用一旦启动则首先打开10个数据库连接,但注意此时数据库连接池的正在使用数字为0--因为你并没有使用这些连接,而空闲的数量则是10。然后你开始登录,假设登录代码使用了一个连接进行查询,那么此时数据库连接池的正在使用数字为1、空闲数为9,这并不需要从数据库打开连接--因为连接池已经准备好了10个给你留着呢。登录结束了,当前连接池的连接数量是多少?当然是0,因为那个连接随着事务的结束已经返还给连接池了。然后同时有11个人在同一秒进行登录,会发生什么:连接池从数据库新申请(打开)了一个连接,连同另外的10个一并送出,这个瞬间连接池的使用数是11个,不过没关系正常情况下过一会儿又会变成0。如果同时有21个人登录呢?那第21个人就只能等前面的某个人登录完毕后释放连接给他。这时连接池开启了20个数据库连接--虽然很可能正在使用数量的已经降为0,那么20个连接会一直保持吗?当然不,连接池会在一定时间内关闭一定量的连接还给数据库,在这个例子里数字是20-10=10,因为只需要保持最小连接数就好了,而这个时间周期也是连接池里配置的。

三:C3P0连接池的配置

3.1:引入数据库连接的jar包和C3P0连接池的jar包

3.2:在src目录下编写c3p0-config.xml

名字必须叫c3p0-config.xml且放在src下  c3p0连接池会自动读取该配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <c3p0-config>

  3. <!-- ==========默认配置========== -->
  4. <default-config>
  5. <property name="driverClass">com.mysql.jdbc.Driver</property>
  6. <property name="jdbcUrl">jdbc:mysql://localhost:3307/shopstore</property>
  7. <property name="user">root</property>
  8. <property name="password">123456</property>
  9. <property name="initialPoolSize">5</property>
  10. <property name="maxPoolSize">20</property>
  11. </default-config>
  12.  
  13. </c3p0-config>

https://www.cnblogs.com/xdp-gacl/p/4002804.html  这篇博客使用的配置文件

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!--
  3. c3p0-config.xml必须位于类路径下面
  4. private static ComboPooledDataSource ds;
  5. static{
  6. try {
  7. ds = new ComboPooledDataSource("MySQL");
  8. } catch (Exception e) {
  9. throw new ExceptionInInitializerError(e);
  10. }
  11. }
  12. -->
  13.  
  14. <c3p0-config>
  15. <!--
  16. C3P0的缺省(默认)配置,
  17. 如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource();”这样写就表示使用的是C3P0的缺省(默认)配置信息来创建数据源
  18. -->
  19. <default-config>
  20. <property name="driverClass">com.mysql.jdbc.Driver</property>
  21. <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy</property>
  22. <property name="user">root</property>
  23. <property name="password">XDP</property>
  24.  
  25. <property name="acquireIncrement">5</property>
  26. <property name="initialPoolSize">10</property>
  27. <property name="minPoolSize">5</property>
  28. <property name="maxPoolSize">20</property>
  29. </default-config>
  30.  
  31. <!--
  32. C3P0的命名配置,
  33. 如果在代码中“ComboPooledDataSource ds = new ComboPooledDataSource("MySQL");”这样写就表示使用的是name是MySQL的配置信息来创建数据源
  34. -->
  35. <named-config name="MySQL">
  36. <property name="driverClass">com.mysql.jdbc.Driver</property>
  37. <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy</property>
  38. <property name="user">root</property>
  39. <property name="password">XDP</property>
  40.  
  41. <property name="acquireIncrement">5</property>
  42. <property name="initialPoolSize">10</property>
  43. <property name="minPoolSize">5</property>
  44. <property name="maxPoolSize">20</property>
  45. </named-config>
  46.  
  47. </c3p0-config>

3.3:编写c3p0的工具类

我使用的工具类,在下面一篇为别人博客的工具类,讲解的不错

  1. package com.itheima.utils;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7.  
  8. import javax.sql.DataSource;
  9.  
  10. import com.mchange.v2.c3p0.ComboPooledDataSource;
  11.  
  12. public class DataSourceUtils {

  13.   //这样写表示使用c3p0默认配置数据源
  14. private static DataSource dataSource = new ComboPooledDataSource();
  15.  
  16. private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
  17.  
  18. //直接可以获取一个连接池
  19. public static DataSource getDataSource() {
  20. return dataSource;
  21. }
  22.  
  23. public static Connection getConnection() throws SQLException{
  24. return dataSource.getConnection();
  25. }
  26.  
  27. // 获取连接对象
  28. public static Connection getCurrentConnection() throws SQLException {
  29.  
  30. Connection con = tl.get();
  31. if (con == null) {
  32. con = dataSource.getConnection();
  33. tl.set(con);
  34. }
  35. return con;
  36. }
  37.  
  38. // 开启事务
  39. public static void startTransaction() throws SQLException {
  40. Connection con = getCurrentConnection();
  41. if (con != null) {
  42. con.setAutoCommit(false);
  43. }
  44. }
  45.  
  46. // 事务回滚
  47. public static void rollback() throws SQLException {
  48. Connection con = getCurrentConnection();
  49. if (con != null) {
  50. con.rollback();
  51. }
  52. }
  53.  
  54. // 提交并且关闭资源及从ThreadLocall中释放
  55. public static void commitAndRelease() throws SQLException {
  56. Connection con = getCurrentConnection();
  57. if (con != null) {
  58. con.commit(); // 事务提交
  59. con.close();// 关闭资源
  60. tl.remove();// 从线程绑定中移除
  61. }
  62. }
  63.  
  64. // 关闭资源方法
  65. public static void closeConnection() throws SQLException {
  66. Connection con = getCurrentConnection();
  67. if (con != null) {
  68. con.close();
  69. }
  70. }
  71.  
  72. public static void closeStatement(Statement st) throws SQLException {
  73. if (st != null) {
  74. st.close();
  75. }
  76. }
  77.  
  78. public static void closeResultSet(ResultSet rs) throws SQLException {
  79. if (rs != null) {
  80. rs.close();
  81. }
  82. }
  83.  
  84. }
  1. package me.gacl.util;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.sql.Statement;
  7. import com.mchange.v2.c3p0.ComboPooledDataSource;
  8.  
  9. /**
  10. * @ClassName: JdbcUtils_C3P0
  11. * @Description: 数据库连接工具类
  12. * @author: 孤傲苍狼
  13. * @date: 2014-10-4 下午6:04:36
  14. *
  15. */
  16. public class JdbcUtils_C3P0 {
  17.  
  18. private static ComboPooledDataSource ds = null;
  19. //在静态代码块中创建数据库连接池
  20. static{
  21. try{
  22. //通过代码创建C3P0数据库连接池
  23. /*ds = new ComboPooledDataSource();
  24. ds.setDriverClass("com.mysql.jdbc.Driver");
  25. ds.setJdbcUrl("jdbc:mysql://localhost:3306/jdbcstudy");
  26. ds.setUser("root");
  27. ds.setPassword("XDP");
  28. ds.setInitialPoolSize(10);
  29. ds.setMinPoolSize(5);
  30. ds.setMaxPoolSize(20);*/
  31.  
  32. //通过读取C3P0的xml配置文件创建数据源,C3P0的xml配置文件c3p0-config.xml必须放在src目录下
  33. //ds = new ComboPooledDataSource();//使用C3P0的默认配置来创建数据源
  34. ds = new ComboPooledDataSource("MySQL");//使用C3P0的命名配置来创建数据源
  35.  
  36. }catch (Exception e) {
  37. throw new ExceptionInInitializerError(e);
  38. }
  39. }
  40.  
  41. /**
  42. * @Method: getConnection
  43. * @Description: 从数据源中获取数据库连接
  44. * @Anthor:孤傲苍狼
  45. * @return Connection
  46. * @throws SQLException
  47. */
  48. public static Connection getConnection() throws SQLException{
  49. //从数据源中获取数据库连接
  50. return ds.getConnection();
  51. }
  52.  
  53. /**
  54. * @Method: release
  55. * @Description: 释放资源,
  56. * 释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象
  57. * @Anthor:孤傲苍狼
  58. *
  59. * @param conn
  60. * @param st
  61. * @param rs
  62. */
  63. public static void release(Connection conn,Statement st,ResultSet rs){
  64. if(rs!=null){
  65. try{
  66. //关闭存储查询结果的ResultSet对象
  67. rs.close();
  68. }catch (Exception e) {
  69. e.printStackTrace();
  70. }
  71. rs = null;
  72. }
  73. if(st!=null){
  74. try{
  75. //关闭负责执行SQL命令的Statement对象
  76. st.close();
  77. }catch (Exception e) {
  78. e.printStackTrace();
  79. }
  80. }
  81.  
  82. if(conn!=null){
  83. try{
  84. //将Connection连接对象还给数据库连接池
  85. conn.close();
  86. }catch (Exception e) {
  87. e.printStackTrace();
  88. }
  89. }
  90. }
  91. }

3.4:编写测试类

  1. package C3P0温习;
  2.  
  3. import java.sql.Connection;
  4. import java.sql.PreparedStatement;
  5. import java.sql.SQLException;
  6.  
  7. import org.junit.Test;
  8.  
  9. public class test {
  10. @Test
  11. public void add() throws SQLException {
  12. // 1.获取一个连接池
  13. Connection conn = DataSourceUtils.getConnection();
  14. // 2.编写sql语句
  15. String sql = "insert into student values(11,'王二','男')";
  16. // 3.编写sql载体
  17. PreparedStatement pst = conn.prepareStatement(sql);
  18. // 4.执行sql语句
  19. int updateRow = pst.executeUpdate();
  20. if (updateRow > 0) {
  21. System.out.println("插入成功");
  22. } else {
  23. System.out.println("插入失败");
  24. }
  25. }
  26. }

C3P0连接池温习1的更多相关文章

  1. c3p0连接池]

    <c3p0-config> <!-- 默认配置 --> <default-config> <property name="jdbcUrl" ...

  2. c3p0连接池获得的Connection执行close方法后是否真的销毁Connection对象?

    问题描述: jfinal做的api系统中,在正常调用接口一段时间后,突然再调用接口的时候,该请求无响应api系统后台也无错误信息 (就是刚开始接口调用是正常的,突然就无响应了) 于是啊,就开始找错误. ...

  3. C3P0连接池在hibernate和spring中的配置

    首先为什么要使用连接池及为什么要选择C3P0连接池,这里就不多说了,目前C3P0连接池还是比较方便.比较稳定的连接池,能与spring.hibernate等开源框架进行整合. 一.hibernate中 ...

  4. C3P0连接池问题,APPARENT DEADLOCK!!! Creating emergency..... [问题点数:20分,结帖人lovekong]

    采用c3p0连接池,每次调试程序,第一次访问时(Tomcat服务器重启后再访问)都会出现以下错误,然后连接库需要很长时间,最终是可以连上的,之后再访问就没问题了,请高手们会诊一下,希望能帮小弟解决此问 ...

  5. HQL查询及Hibernate对c3p0连接池的支持

    //HQL查询 // auto-import要设置true,如果是false,写HQL时要指定类的全名 //查询全部列 Query query = session.createQuery(" ...

  6. C3P0连接池详解及配置

    C3P0连接池详解及配置 本人使用的C3P0的jar包是:c3p0-0.9.1.jar <bean id = "dataSource" class = "com.m ...

  7. 使用c3p0连接池

    首先我们需要知道为什么要使用连接池:因为jdbc没有保持连接的能力,一旦超过一定时间没有使用(大约几百毫秒),连接就会被自动释放掉,每次新建连接都需要140毫秒左右的时间而C3P0连接池会池化连接,随 ...

  8. C3P0连接池详细配置

    C3P0连接池详细配置 转自http://msq.javaeye.com/blog/60387 <c3p0-config> <default-config> <!--当连 ...

  9. Maven 工程下 Spring MVC 站点配置 (三) C3P0连接池与@Autowired的应用

    Maven 工程下 Spring MVC 站点配置 (一) Maven 工程下 Spring MVC 站点配置 (二) Mybatis数据操作 前两篇文章主要是对站点和数据库操作配置进行了演示,如果单 ...

随机推荐

  1. C# 实现Jwtbearer Authentication

    Jwtbearer Authentication 什么是JWT JWT(JSON Web Token), 顾名思义就是在Web上以JSON格式传输的Token(RFC 7519). 该Token被设计 ...

  2. C#面向对象之封装。

    封装是面向对象的基础和重要思想之一,今天具体的了解封装这一特性后发现其实自己已经接触过很多关于封装的内容了. 一.什么是封装. 封装的概念:将具体的实现细节装到一个容器中,封闭或隐藏起来(使用访问修饰 ...

  3. SQL语句NOT IN优化之换用NOT EXISTS

    NOT IN查询示例(示例背景描述:根据条件查询Questions表得到的数据基本在PostedData表中不存在,为完全保证查询结果在PostedData表中不存在,使用NOT IN): SET S ...

  4. C#与C++数据类型比较及结构体转换[整理]

    //c++:HANDLE(void   *)                          ----    c#:System.IntPtr//c++:Byte(unsigned   char)  ...

  5. openssl基本原理 + 生成证书 + 使用实例

    前期准备 : 安装xampp:打开文件E:\xampp\apache\bin\openssl.exe  右键 以管理员身份运行 ------转载自 https://blog.csdn.net/oldm ...

  6. 从零开始学安全(十三)●SQL server 2008 R2 安装

    安装过程1.下载并解压 sql_server_2008_r2_enterprise 点击 setup . 2.打开后如图,点击左侧的 安装 ,再点击右边的 全新安装或向现有安装添加功能. 3.安装支持 ...

  7. mybatis_06SQL片段

    个人概要: SQL片段在使用if where的基础上,将if,where语句装到SQL标签内,在数据库操作元素内引用 Mybatis提供了SQL片段的功能,可以提高SQL的可重用性. <!--声 ...

  8. 设计模式—装饰模式的C++实现

    这是Bwar在2009年写的设计模式C++实现,代码均可编译可运行,一直存在自己的电脑里,曾经在团队技术分享中分享过,现搬到线上来. 1. 装饰模式简述 1.1 目的 动态地给一个对象添加一些额外的职 ...

  9. 不创建实体对象,利用newstonjson得到json格式字符串,键对应的值

    1.Json字符串嵌套格式解析 string jsonText = "{\"beijing\":{\"zone\":\"海淀\", ...

  10. nodeJs express mongodb 建站(mac 版)

    基本环境 homebrew.node.npm.express.mongodb 1.node .npm : (1)辅助工具:homebrew安装(mac下一个软件管理工具,相当于Red hat的yum, ...