5. JDBC之数据库连接池——Part1

Posted 3S丶Python丶Java学堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5. JDBC之数据库连接池——Part1相关的知识,希望对你有一定的参考价值。

为了避免频繁的创建数据库连接,数据库连接池技术应运而生。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。


1
 池参数(所有池参数都有默认值)
5. JDBC之数据库连接池——Part1


  • 初始大小:10个

  • 最小空闲连接数:3个

  • 增量:一次创建的最小单位(5个)

  • 最大空闲连接数:12个

  • 最大连接数:20个

  • 最大的等待时间:1000毫秒

2
 四大连接参数
5. JDBC之数据库连接池——Part1


连接池也是使用四大连接参数来完成创建连接对象!


3
 实现的接口
5. JDBC之数据库连接池——Part1


连接池必须实现:javax.sql.DataSource接口!


连接池返回的Connection对象,它的close()方法与众不同!调用它的close()不是关闭,而是把连接归还给池!


4
数据库连接池
5. JDBC之数据库连接池——Part1


为了获取数据库连接对象(Connection),JDBC提供了javax.sql.DataSource接口,它负责与数据库建立连接,并定义了返回值为Connection对象的方法,具体如下。


  • Connection getConnection()

  • Connection getConnection(String username, String password)

4.1 数据库连接池的概念

用池来管理Connection,这可以重复使用Connection。有了池,所以我们就不用自己来创建Connection,而是通过池来获取Connection对象。当使用完Connection后,调用Connection的close()方法也不会真的关闭Connection,而是把Connection“归还”给池。池就可以再利用这个Connection对象了


5. JDBC之数据库连接池——Part1

4.2 JDBC数据库连接池接口(DataSource)

Java为数据库连接池提供了公共的接口:javax.sql.DataSource,各个厂商可以让自己的连接池实现这个接口。这样应用程序可以方便的切换不同厂商的连接池!


4.3 自定义连接池(ItcastPool)

分析:ItcastPool需要有一个List,用来保存连接对象。在ItcastPool的构造器中创建5个连接对象放到List中!当用人调用了ItcastPool的getConnection()时,那么就从List拿出一个返回。当List中没有连接可用时,抛出异常


我们需要对Connection的close()方法进行增强,所以我们需要自定义ItcastConnection类,对Connection进行装饰!即对close()方法进行增强。因为需要在调用close()方法时把连接“归还”给池,所以ItcastConnection类需要拥有池对象的引用,并且池类还要提供“归还”的方法


5. JDBC之数据库连接池——Part1

ItcastPool.java

public class ItcastPool implements DataSource {    
  private static Properties props = new Properties();    
    private List<Connection> list = new ArrayList<Connection>();    
     static {         InputStream in = ItcastPool.class.getClassLoader()              .getResourceAsStream("dbconfig.properties");        
        try {           props.load(in);           Class.forName(props.getProperty("driverClassName"));        } catch (Exception e) {            
          throw new RuntimeException(e);        }    }    
public ItcastPool() throws SQLException {        
 for (int i = 0; i < 5; i++) {    Connection con = DriverManager.getConnection(      props.getProperty("url"), props.getProperty("username"),    props.getProperty("password"));    ItcastConnection conWapper = new ItcastConnection(con, this);    list.add(conWapper);   } }    
public void add(Connection con) {      list.add(con);    }  
public Connection getConnection() throws SQLException {        
    if(list.size() > 0) {            
      return list.remove(0);     }        
    throw new SQLException("没连接了");    }    ...... }

ItcastConnection.java

public class ItcastConnection extends ConnectionWrapper {   
   private ItcastPool pool;    
   public ItcastConnection(Connection con, ItcastPool pool) {        
       super(con);        
       this.pool = pool;    }    
   @Override   public void close() throws SQLException {       pool.add(this);   }

}


5
 DBCP
5. JDBC之数据库连接池——Part1


DBCP是数据库连接池(DataBase Connection Pool)的简称,是Apache组织下的开源连接池实现,也是Tomcat服务器使用的连接池组件。单独使用DBCP数据源时,需要在应用程序中导入两个JAR包,具体如下。


  • commons-dbcp.jar包

  • commons-pool.jar包

5.1 什么是DBCP?

DBCP是Apache提供的一款开源免费的数据库连接池!


Hibernate3.0之后不再对DBCP提供支持!因为Hibernate声明DBCP有致命的缺欠!DBCP因为Hibernate的这一毁谤很是生气,并且说自己没有欠缺


5.2 DBCP的使用

public void fun1() throws SQLException {
  BasicDataSource ds = new BasicDataSource();
  ds.setUsername("root");
  ds.setPassword("123");
  ds.setUrl("jdbc:mysql://localhost:3306/mydb1");
  ds.setDriverClassName("com.mysql.jdbc.Driver");

  ds.setMaxActive(20);
  ds.setMaxIdle(10);
  ds.setInitialSize(10);
  ds.setMinIdle(2);
  ds.setMaxWait(1000);

  Connection con = ds.getConnection();
  System.out.println(con.getClass().getName());
  con.close();
}

5.3 DBCP的配置信息

下面是对DBCP的配置介绍:


#基本配置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb1
username=root
password=123#初始化池大小,即一开始池中就会有10个连接对象
#默认值为0
initialSize=0#最大连接数,如果设置maxActive=50时,
#池中最多可以有50个连接,
#当然这50个连接中包含被使用的和没被使用的(空闲) #你是一个包工头,你一共有50个工人,但这50个工人有的当前正在工作,
#有的正在空闲默认值为8,如果设置为非正数,表示没有限制!即无限大 maxActive=8 #最大空闲连接 #当设置maxIdle=30时,你是包工头,你允许最多有20个工人空闲,
#如果现在有30个空闲工人,那么要开除10个 #默认值为8,如果设置为负数,表示没有限制!即无限大 maxIdle=8 #最小空闲连接 #如果设置minIdel=5时,如果你的工人只有3个空闲,
那么你需要再去招2个回来,保证有5个空闲工人 #默认值为0 minIdle=0 #最大等待时间 #当设置maxWait=5000时,现在你的工作都出去工作了,
#又来了一个工作,需要一个工人。 #这时就要等待有工人回来,如果等待5000毫秒还没回来,那就抛出异常 #没有工人的原因:最多工人数为50,已经有50个工人了,不能再招了,
#但50人都出去工作了。 #默认值为-1,表示无限期等待,不会抛出异常。 maxWait=-1 #连接属性 #就是原来放在url后面的参数,可以使用connectionProperties来指定 #如果已经在url后面指定了,那么就不用在这里指定了。 #useServerPrepStmts=true,MySQL开启预编译功能 #cachePrepStmts=true,MySQL开启缓存PreparedStatement功能, #prepStmtCacheSize=50,缓存PreparedStatement的上限 #prepStmtCacheSqlLimit=300,当SQL模板长度大于300时,就不再缓存它 connectionProperties=useUnicode=true;
characterEncoding=UTF8;
useServerPrepStmts=true;
cachePrepStmts=true;
prepStmtCacheSize=50;
prepStmtCacheSqlLimit=300 #连接的默认提交方式 #默认值为true defaultAutoCommit=true #连接是否为只读连接 #Connection有一对方法:setReadOnly(boolean)和isReadOnly() #如果是只读连接,那么你只能用这个连接来做查询 #指定连接为只读是为了优化!这个优化与并发事务相关! #如果两个并发事务,对同一行记录做增、删、改操作,是不是一定要隔离它们啊? #如果两个并发事务,对同一行记录只做查询操作,那么是不是就不用隔离它们了? #如果没有指定这个属性值,那么是否为只读连接,这就由驱动自己来决定了。
#即Connection的实现类自己来决定! defaultReadOnly=false #指定事务的事务隔离级别 #可选值:
NONE,READ_UNCOMMITTED,
READ_COMMITTED,
REPEATABLE_READ,
SERIALIZABLE #如果没有指定,那么由驱动中的Connection实现类自己来决定

defaultTransactionIsolation=REPEATABLE_READ


6
 C3P0
5. JDBC之数据库连接池——Part1


C3P0是目前最流行的开源数据库连接池之一,它实现了DataSource数据源接口,支持JDBC2和JDBC3的标准规范,易于扩展并且性能优越,著名的开源框架Hibernate和 Spring都支持该数据源。在使用C3P0数据源开发时,需要了解C3P0中DataSource接口的实现类ComboPooledDataSource,它是C3P0的核心类,提供了数据源对象的相关方法,该类的常用方法介绍如下表所示。


6.1 C3P0简介

C3P0也是开源免费的连接池!C3P0被很多人看好!


6.2 C3P0的使用

C3P0中池类是:ComboPooledDataSource。


public void fun1() throws PropertyVetoException, SQLException {
  ComboPooledDataSource ds = new ComboPooledDataSource();
  ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb1");
  ds.setUser("root");
  ds.setPassword("123");
  ds.setDriverClass("com.mysql.jdbc.Driver");

  ds.setAcquireIncrement(5);
  ds.setInitialPoolSize(20);
  ds.setMinPoolSize(2);
  ds.setMaxPoolSize(50);

  Connection con = ds.getConnection();
  System.out.println(con);
  con.close();
}

配置文件要求:


  • 文件名称:必须叫c3p0-config.xml

  • 文件位置:必须在src下

c3p0也可以指定配置文件,而且配置文件可以是properties,也可骒xml的。当然xml的高级一些了。但是c3p0的配置文件名必须为c3p0-config.xml,并且必须放在类路径下。


<?xml version="1.0" encoding="UTF-8"?><c3p0-config>
    <default-config>
        <property name="jdbcUrl">
               jdbc:mysql://localhost:3306/mydb1
           </property>        <property name="driverClass">com.mysql.jdbc.Driver
           </property>        <property name="user">root</property>        <property name="password">123</property>        <property name="acquireIncrement">3</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">2</property>        <property name="maxPoolSize">10</property>    </default-config>    <named-config name="oracle-config">        <property name="jdbcUrl">
               jdbc:mysql://localhost:3306/mydb1
           </property>        <property name="driverClass">com.mysql.jdbc.Driver
           </property>        <property name="user">root</property>        <property name="password">123</property>        <property name="acquireIncrement">3</property>        <property name="initialPoolSize">10</property>        <property name="minPoolSize">2</property>        <property name="maxPoolSize">10</property>    </named-config></c3p0-config>

c3p0的配置文件中可以配置多个连接信息,可以给每个配置起个名字,这样可以方便的通过配置名称来切换配置信息。上面文件中默认配置为mysql的配置,名为oracle-config的配置也是mysql的配置,呵呵


public void fun2() throws PropertyVetoException, SQLException {
  ComboPooledDataSource ds = new ComboPooledDataSource();
  Connection con = ds.getConnection();
  System.out.println(con);
  con.close();
}
public void fun2() throws PropertyVetoException, SQLException {  ComboPooledDataSource ds =
           new ComboPooledDataSource("orcale-config");  Connection con = ds.getConnection();  System.out.println(con);  con.close();

}






以上是关于5. JDBC之数据库连接池——Part1的主要内容,如果未能解决你的问题,请参考以下文章

JavaWeb之数据库连接池

JavaWeb之数据库连接池

jdbc之连接池

Java之JDBC连接池

JDBC第三天~JDBC之事务批处理自动生成主键连接池重构设计

JDBC之Druid连接池的使用