JDBC 数据连接池
在系统初始化的时候,将数据库连接作为对象存储在内存中,当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已经建立的空闲连接对象。使用完毕后,用户 也并非将连接关闭,而是将连接放回连接池中,以供下一个请求访问使用。而连接的建立、断开都由连 接池自身来管理。同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数 以及每个连接的最大使用次数、最大空闲时间等等,也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
目前连接池可分为:自定义连接池、DBCP连接池、C3P0连接池、Druid德鲁伊连接池
最小连接数: 是数据库一直保持的数据库连接数,所以如果应用程序对数据库连接的使用量不大,将有大量的数据库 资源被浪费。
初始化连接数: 连接池启动时创建的初始化数据库连接数量。
最大连接数: 是连接池能申请的最大连接数,如果数据库连接请求超过此数,后面的数据库连接请求被加入到等待队 列中。
最大等待时间: 当没有可用连接时,连接池等待连接被归还的最大时间,超过时间则抛出异常,可设置参数为0或者负 数使得无限等待(根据不同连接池配置)。
DBCP | c3p0 | Druid | |
---|---|---|---|
最小连接数 | minIdle(0) | minPoolSize(3) | minIdle(0) |
初始化连接数 | initialSize(0) | initialPoolSIize(3) | initialSize(0) |
最大连接数 | maxTotal(8) | maxPoolSize(15) | maxActive(8) |
最大等待时间 | maxWaitMillis(毫秒) | maxIdleTime(0秒) | maxWait(毫秒) |
一、自定义连接池
通过自定义的方式实现连接池!分析连接池类应该包含特定的属性和方法!
属性: 集合 放置Connection
方法:获取连接方法
回收连接方法
public class Pool{
static LinkedList<Connection> list = new LinkedList<Connection>();
static{
for (int i = 0; i < 10; i++) {
Connection connection = JDBCUtils.newInstance().getConnection();
list.add(connection);
}
}//static
/**
* 从连接池子中获取连接的方式
* @return
*/
public static Connection getConnection(){
if (list.isEmpty()) {
//JDBCUtils类是自定义类,封装了连接数据库的信息代码
Connection connection = JDBCUtils.newInstance().getConnection();
list.addLast(connection);
}
Connection conn = list.removeFirst();
return conn;
}//getConnection
/**
* 返回到连接池子中
*/
public static void addBack(Connection conn){
if (list.size() >= 10) {
try {
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
list.addLast(conn); //10
}
}//addBack
/**
* 获取连接池子中连接数量的方法
*/
public static int getSize(){
return list.size();
}
}//Pool
注1:在DBCP连接池的配置中,还有一个maxIdle的属性,表示最大空闲连接数,超过的空闲连接将被释 放,默认值为8。对应的该属性在Druid连接池已不再使用,配置了也没有效果,c3p0连接池则没有对 应的属性。
注2:数据库连接池在初始化的时候会创建initialSize个连接,当有数据库操作时,会从池中取出一个连 接。如果当前池中正在使用的连接数等于maxActive,则会等待一段时间,等待其他操作释放掉某一个 连接,如果这个等待时间超过了maxWait,则会报错;如果当前正在使用的连接数没有达到 maxActive,则判断当前是否空闲连接,如果有则直接使用空闲连接,如果没有则新建立一个连接。在 连接使用完毕后,不是将其物理连接关闭,而是将其放入池中等待其他操作复用。
二、DBCP连接池
> DBCP是一个依赖Jakarta commons-pool对象池机制的数据库连接池.DBCP可以直接的在应用程序中 使用,Tomcat的数据源使用的就是DBCP。
使用DBCP 需要导入相应的jar包
mysql-jdbc.jar
commons-dbcp.jar
commons-pool.jar
硬编码使用DBCP
所谓的硬编码方式就是在代码中添加配置
public void testHard() throws SQLException{
// 硬编码 使用DBCP连接池子
BasicDataSource source = new BasicDataSource();
//设置连接的信息
source.setDriverClassName("com.mysql.jdbc.Driver");
source.setUrl("jdbc:mysql://localhost:3306/day2");
source.setUsername("root");
source.setPassword("111");
Connection connection = source.getConnection();
String sql = "select * from student";
Statement createStatement = connection.createStatement();
ResultSet executeQuery = createStatement.executeQuery(sql);
while (executeQuery.next()) {
System.out.println(executeQuery.getString(2));
}
connection.close(); //回收
}
软编码使用DBCP
> 所谓的软编码,就是在项目中添加配置文件,这样就不需要每次代码中添加配合!
-
项目中添加配置
文件名称: info.properties 文件位置: src下
-
连接设置
#连接设置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/day2 username=root password=111 #<!-- 初始化连接 --> initialSize=10 #最大连接数量 maxActive=50 #<!-- 最大空闲连接 --> maxIdle=20 #<!-- 最小空闲连接 --> minIdle=5 #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 --> maxWait=6000
-
DButils工具类 代码实现
//1.创建dbcp的工具类对象 static BasicDataSource datasource=new BasicDataSource(); //2.加载驱动 static { try { //加载属性文件 //1.使用工具类 ,参数是属性文件的文件名(不要加后缀) ResourceBundle bundle = ResourceBundle.getBundle("db"); driverClass = bundle.getString("driverclass"); url = bundle.getString("url"); username = bundle.getString("uname"); password = bundle.getString("upass"); init=bundle.getString("initsize"); //2.将驱动地址等信息传递给dbcp datasource.setDriverClassName(driverClass); datasource.setUrl(url); datasource.setUsername(username); datasource.setPassword(password); datasource.setInitialSize(Integer.parseInt(init)); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } }// static //3.获得连接 public static Connection getConn() { try { con= datasource.getConnection(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } return con; }
三、 C3P0连接池
> c3p0是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate一起发布,包括了实现jdbc3和 jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
c3p0与dbcp区别
- dbcp没有自动回收空闲连接的功能 c3p0有自动回收空闲连接功能
- dbcp需要手动设置配置文件 c3p0不需要手动设置
实现方式
-
手动设置 ComboPooledDataSource
-
加载配置文件方式
src/c3p0-config.xml(文件名固定) ComboPooledDataSource cpds = new ComboPooledDataSource(); 加载 文件中 <default-config>中的配置 ComboPooledDataSource cpds = new ComboPooledDataSource("aaa"); 加载 <named-config name="aaa"> 中的配置
-
实现步骤
导入jar包
c3p0-0.9.1.2.jar
mysql-connector-java-5.0.8.jar
-
添加配置文件
> c3p0是在外部添加配置文件,工具直接进行应用,因为直接引用,所以要求固定的命名和文件位置
文件位置: src
文件命名:c3p0-config.xml/c3p0-config.properties
<?xml version="1.0" encoding="utf-8"?>
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<!-- 基本配置 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day2</property>
<property name="user">root</property>
<property name="password">111</property>
<!--扩展配置-->
<!-- 连接超过30秒报错-->
<property name="checkoutTimeout">30000</property>
<!--30秒检查空闲连接 -->
<property name="idleConnectionTestPeriod">30</property>
<property name="initialPoolSize">10</property>
<!-- 30秒不适用丢弃-->
<property name="maxIdleTime">30</property>
<property name="maxPoolSize">100</property>
<property name="minPoolSize">10</property>
<property name="maxStatements">200</property>
</default-config>
<!-- 命名的配置 -->
<named-config name="abc">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/day2</property>
<property name="user">root</property>
<property name="password">111</property>
<!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="acquireIncrement">5</property>
<property name="initialPoolSize">20</property>
<property name="minPoolSize">10</property>
<property name="maxPoolSize">40</property>
<property name="maxStatements">20</property>
<property name="maxStatementsPerConnection">5</property>
</named-config>
</c3p0-config>
注意: c3p0的配置文件内部可以包含命名配置文件和默认配置文件!默认是选择默认配置!如果需要切换 命名配置可以在创建c3p0连接池的时候填入命名即可!
-
定义代码
Connection con=null; ComboPooledDataSource db=new ComboPooledDataSource("abc"); public Connection getCon(){ try { con=db.getConnection(); //获得连接后返回的 结果集 System.out.println("初始化的链接数量:"+db.getInitialPoolSize()); } catch (SQLException e) { e.printStackTrace(); } return con; }
四、Druid(德鲁伊)连接池
使用步骤
- 导入jar包
druid-1.0.9.jar
-
配置文件 dbcpconfig.properties
属性文件内容
<!-- 基本配置 --> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="jdbcUrl">jdbc:mysql://localhost:3306/day2</property> <property name="user">root</property> <property name="password">111</property>
-
编写工具类
/**
* 阿里的数据库连接池
* 性能最好的
* Druid
* */
public class DruidUtils {
//声明连接池对象
private static DruidDataSource ds;
static{
///实例化数据库连接池对象
ds=new DruidDataSource();
//实例化配置对象
Properties properties=new Properties();
try {
//加载配置文件内容
properties.load(DruidUtils.class.getResourceAsStream("dbcpconfig.properties"));
//设置驱动类全称
ds.setDriverClassName(properties.getProperty("driverClassName"));
//设置连接的数据库
ds.setUrl(properties.getProperty("url"));
//设置用户名
ds.setUsername(properties.getProperty("username"));
//设置密码
ds.setPassword(properties.getProperty("password"));
//设置最大连接数量
ds.setMaxActive(Integer.parseInt(properties.getProperty("maxActive")));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}//static
//获取连接对象
public static Connection getConnection() {
try {
return ds.getConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}//DruidUtils
注:在Druid连接池的配置中,driverClassName可配可不配,如果不配置会根据url自动识别dbType(数 据库类型),然后选择相应的driverClassName。