纲要:
1.数据库连接池 概念
2.连接池技术分类、
3.具体用法
a.C3P0连接池技术
b.Druid连接池技术
数据库连接池
一:
1)概念:
a.其实就是一个容器(集合),存放数据库连接的容器。
b.当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。
2) 原理:
连接池基本的思想是在系统初始化的时候,将数据库连作为对象存储在内存中,
当用户需要访问数据库时,并非建立一个新的连接,而是从连接池中取出一个已建立的空闲连接对象。
使用完毕后,用户也并非将连接关闭,而是将连接放回连接池中,
以供下一个请求访问使用。而连接的建立、断开都由连接池自身来管理。
同时,还可以通过设置连接池的参数来控制连接池中的初始连接数、连接的上下限数以及每个连接的最大使用次数、最大空闲时间等等。
也可以通过其自身的管理机制来监视数据库连接的数量、使用情况等。
3) 实现:
标准接口:DataSource javax.sql包下的
方法:
* 获取连接:getConnection()
* 归还连接:Connection.close()
(如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了。而是归还连接)
二:
分类
1)C3P0:
是一个开放源代码的JDBC连接池,它在lib目录中与Hibernate [2] 一起发布,包括了实现jdbc3和jdbc2扩展规范说明的Connection 和Statement 池的DataSources 对象。
2)Druid:
Druid不仅是一个数据库连接池,还包含一个ProxyDriver、一系列内置的JDBC组件库、一个SQL Parser。支持所有JDBC兼容的数据库,包括Oracle、MySql、Derby、Postgresql、SQL Server、H2等。
Druid针对Oracle和MySql做了特别优化,
比如:
Oracle的PS Cache内存占用优化
MySql的ping检测优化
Druid提供了MySql、Oracle、Postgresql、SQL-92的SQL的完整支持,这是一个手写的高性能SQL Parser,支持Visitor模式,使得分析SQL的抽象语法树很方便。
简单SQL语句用时10微秒以内,复杂SQL用时30微秒。
通过Druid提供的SQL Parser可以在JDBC层拦截SQL做相应处理,比如说分库分表、审计等。Druid防御SQL注入攻击的WallFilter,就是通过Druid的SQL Parser分析语义实现的
3)Proxool:
是一个Java SQL Driver驱动程序,提供了对选择的其它类型的驱动程序的连接池封装。可以非常简单的移植到现存的代码中,完全可配置,快速、成熟、健壮。可以透明地为现存的JDBC驱动程序增加连接池功能。
4)Jakarta DBCP:
DBCP是一个依赖Jakartacommons-pool对象池机制的数据库连接池。DBCP可以直接的在应用程序中使用。
5)DDConnectionBroker:
是一个简单、轻量级的数据库连接池。
6)DBPool:
是一个高效、易配置的数据库连接池。它除了支持连接池应有的功能之外,还包括了一个对象池,使用户能够开发一个满足自己需求的数据库连接池。
7)XAPool:
是一个XA数据库连接池。它实现了javax.sql.XADataSource并提供了连接池工具。
8)Primrose:
是一个Java开发的数据库连接池。当前支持的容器包括Tomcat4&5、Resin3与JBoss3。它同样也有一个独立的版本,可以在应用程序中使用而不必运行在容器中。Primrose通过一个WEB接口来控制SQL处理的追踪、配置,以及动态池管理。在重负荷的情况下可进行连接请求队列处理。
9)SmartPool:
是一个连接池组件,它模仿应用服务器对象池的特性。SmartPool能够解决一些临界问题如连接泄漏(connection leaks)、连接阻塞、打开的JDBC对象(如Statements、PreparedStatements)等。SmartPool的特性包括:
支持多个pool、自动关闭相关联的JDBC对象、在所设定time-outs之后察觉连接泄漏、追踪连接使用情况、强制启用最近最少用到的连接、把SmartPool“包装”成现存的一个pool
10)MiniConnectionPoolManager:
是一个轻量级JDBC数据库连接池。它只需要Java1.5(或更高)并且没有依赖第三方包。
11)BoneCP:
是一个快速、开源的数据库连接池。帮用户管理数据连接,让应用程序能更快速地访问数据库。比C3P0/DBCP连接池速度快25倍。
三:
具体用法 1:C3P0连接池技术
* 步骤:
1. 导入jar包 (两个) c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar ,
* 不要忘记导入数据库驱动jar包
2. 定义配置文件:
* 名称: c3p0.properties 或者 c3p0-config.xml
* 路径:直接将文件放在src目录下即可。
3. 创建核心对象 数据库连接池对象 ComboPooledDataSource
4. 获取连接: getConnectionJDBCUtils
1)导入配置文件
使用c3p0所需要的配置文件:c3p0-config.xml【配置文件一定放在src
路径下 ,其中的“问号”为根据个人配置必须
修改的内容】
<?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/???</property>
<property name="user">???</property>
<property name="password">???</property>
<!-- 其他设置 -->
<!-- 连接超时设置30秒 -->
<property name="checkoutTimeout">3000</property>
<!-- 30秒检查一次connection的空闲 -->
<property name="idleConnectionTestPeriod">30</property>
<!--初始化的池大小 -->
<property name="initialPoolSize">2</property>
<!-- 最多的一个connection空闲时间 -->
<property name="maxIdleTime">30</property>
<!-- 最多可以有多少个连接connection -->
<property name="maxPoolSize">5</property>
<!-- 最少的池中有几个连接 -->
<property name="minPoolSize">2</property>
<!-- 批处理的语句 -->
<property name="maxStatements">50</property>
<!-- 每次增长几个连接 -->
<property name="acquireIncrement">3</property>
</default-config>
</c3p0-config>
2):导入JDBCUtils工具类
package com.itheima.utils;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcUtils {
private static DataSource ds = new ComboPooledDataSource();
/**
* 获取连接
* @return
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
/**
* 获取数据库连接池
* @return
*/
public static DataSource getDataSource(){
return ds;
}
/**
* 释放资源
*
* @param stmt
* @param conn
*/
public static void close(ResultSet rs, Statement stmt, Connection conn) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
3):项目中代码实现示例
其中个别内容需根据个人项目情况
进行修改
@Test
public void test1() throws SQLException {
//1. 创建连接池对象 --- 会自动的加载配置文件 c3p0-config.xml
ComboPooledDataSource ds = new ComboPooledDataSource();
//2. 获取连接
Connection connection = ds.getConnection();
//3.定义sql语句
String sql = "select * from student ";
//4.获取执行sql的对象 Statement
Statement stmt = connection.createStatement();
//5.执行sql
ResultSet rs = stmt.executeQuery(sql);
//6.处理结果
while(rs.next()){
System.out.println(rs.getObject("name")+" "+rs.getObject("age"));
}
//7.释放资源
JdbcUtils.close(rs,stmt,connection);
}
具体用法 2:Druid连接池技术
* 步骤:
1. 导入jar包 druid-1.0.9.jar
2. 定义配置文件:
* 是properties形式的
* 可以叫任意名称,可以放在任意目录下
3. 加载配置文件。Properties
4. 获取数据库连接池对象:通过工厂来来获取 DruidDataSourceFactory
5. 获取连接:getConnection
1):导入Druid配置文件
使用druid所需要的配置文件:druid.properties【配置文件一定放在src
路径下 ,其中的“问号”为根据个人配置必须
修改的内容】
# 连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/???
username=???
password=???
# 初始化连接
initialSize=10
#最大连接数量
maxActive=50
# 最大空闲连接
maxIdle=20
# 最小空闲连接
minIdle=5
# 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒
maxWait=60000
2):导入JDBCUtils工具类
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/*
1. 声明静态数据源成员变量
2. 创建连接池对象
3. 定义公有的得到数据源的方法
4. 定义得到连接对象的方法
5. 定义关闭资源的方法
*/
public class JDBCUtils {
// 1. 声明静态数据源成员变量
private static DataSource ds;
// 2. 创建连接池对象
static {
// 加载配置文件中的数据
InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties");
Properties pp = new Properties();
try {
pp.load(is);
// 创建连接池,使用配置文件中的参数
ds = DruidDataSourceFactory.createDataSource(pp);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
// 3. 定义公有的得到数据源的方法
public static DataSource getDataSource() {
return ds;
}
// 4. 定义得到连接对象的方法
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
// 5.定义关闭资源的方法
public static void close(Connection conn, Statement stmt, ResultSet rs) {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {}
}
}
// 6.重载关闭方法
public static void close(Connection conn, Statement stmt) {
close(conn, stmt, null);
}
}
3):项目中代码实现示例
其中个别内容需根据个人项目情况
进行修改
@Test
public void test1() throws Exception {
//1. 加载配置文件
Properties properties = new Properties();
properties.load(DruidDataSourceTest.class.getClassLoader().getResourceAsStream("druid.properties"));
// 2. 创建数据库连接池
DataSource ds = DruidDataSourceFactory.createDataSource(properties);
//3. 获取连接
Connection connection = ds.getConnection();
//4.定义sql语句
String sql = "select * from student ";
//4.获取执行sql的对象 Statement
Statement stmt = connection.createStatement();
//5.执行sql
ResultSet rs = stmt.executeQuery(sql);
//6.处理结果
while(rs.next()){
System.out.println(rs.getObject("name")+" "+rs.getObject("age"));
}
//7.释放资源
JdbcUtils.close(rs,stmt,connection);
}