5. JDBC之数据库连接池——Part1
Posted 3S丶Python丶Java学堂
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了5. JDBC之数据库连接池——Part1相关的知识,希望对你有一定的参考价值。
为了避免频繁的创建数据库连接,数据库连接池技术应运而生。数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用现有的数据库连接,而不是重新建立。
初始大小:10个
最小空闲连接数:3个
增量:一次创建的最小单位(5个)
最大空闲连接数:12个
最大连接数:20个
最大的等待时间:1000毫秒
连接池也是使用四大连接参数来完成创建连接对象!
连接池必须实现:javax.sql.DataSource接口!
连接池返回的Connection对象,它的close()方法与众不同!调用它的close()不是关闭,而是把连接归还给池!
为了获取数据库连接对象(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对象了
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类需要拥有池对象的引用,并且池类还要提供“归还”的方法
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); }
}
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
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的主要内容,如果未能解决你的问题,请参考以下文章