JDBC——连接池概念、DBCP、c3p0、Druid及其工具类
目录
JDBC连接池
数据库连接池的概念
跳转到目录
其实就是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器。为什么存在数据库连接池:
因为与数据库建立连接底层是向操作系统申请的资源,由于每次申请连接资源后,我们就把资源给释放了. 下次需要操作数据库又需要去申请,这个操作是比较耗时的,所以就出现了数据库连接池的技术。优点:
节约资源、用户访问高效
数据库连接池的实现
- 实现接口
DataSource
javax.sql包下的接口
方法getConnection()
获取连接Connection.close()
归还连接一般我们不去实现DataSource,又提供数据库的厂商来实现。
DBCP连接池
跳转到目录
使用步骤:
1. 导入jar包(两个) commons-dbcp-1.4.jar
、commons-pool-1.5.6.jar
DBCP工具类
package com.sunny.utils;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
public class DBCPUtil {
private static Properties p = new Properties();
private static DataSource ds;
static {
try {
// 从classpath的根路径下去寻找dbcp.properties文件
InputStream inputStream = Thread.currentThread().
getContextClassLoader().getResourceAsStream("dbcp.properties");
p.load(inputStream);
ds = BasicDataSourceFactory.createDataSource(p);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取连接的方法
*
* @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(Statement stmt, Connection conn) {
close(null, stmt, conn);
}
/**
* 释放资源
*
* @param rs
* @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();
}
}
}
}
- DBCPTest
package com.sunny.datasource.DBCP;
import com.sunny.utils.DBCPUtil;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class DBCPTest1 {
// 查询zy数据库中emp表中员工的姓名和工资
@Test
public void testQueryEmp() throws SQLException {
String sql = "SELECT * FROM emp";
Connection conn = DBCPUtil.getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
while (rs.next()){
long id = rs.getLong("id");
String ename = rs.getString("ename");
double salary = rs.getDouble("salary");
System.out.println(id+"\t"+ename+"\t"+salary);
}
DBCPUtil.close(rs, ps, conn);
}
}
c3p0连接池
跳转到目录
使用步骤:
1. 导入jar包(两个) c3p0-0.9.5.2.jar
、mchange-commons-java-0.2.12.jar
2. 定义配置文件 c3p0.properties
或者 c3p0-config.xml
直接放在src目录下
3. 创建数据库连接池对象 ComboPooledDataSource
4. 获取连接 getConnection
/*
c3p0演示
*/
public class C3P0Demo1 {
public static void main(String[] args) throws SQLException {
//1. 创建数据库连接池对象,可以使用默认配置,也可以使用指定配置
//DataSource ds = new ComboPooledDataSource();
DataSource ds = new ComboPooledDataSource("otherc3p0");
//2. 获取连接对象
Connection conn = ds.getConnection();
//3. 打印
System.out.println(conn);
}
}
c3p0-config.xml
使用此名字会自动加载该配置文件
<c3p0-config>
<!-- 使用默认的配置读取连接池对象 -->
<default-config>
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db</property>
<property name="user">root</property>
<property name="password">1111</property>
<!-- 连接池参数 -->
<!-- 初始化申请的连接池对象 -->
<property name="initialPoolSize">5</property>
<!-- 最大的连接数量 -->
<property name="maxPoolSize">10</property>
<!-- 超时时间 -->
<property name="checkoutTimeout">3000</property>
</default-config>
<!-- 使用otherc3p0的配置 -->
<named-config name="otherc3p0">
<!-- 连接参数 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/db</property>
<property name="user">root</property>
<property name="password">1111</property>
<!-- 连接池参数 -->
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">8</property>
<property name="checkoutTimeout">1000</property>
</named-config>
</c3p0-config>
除了这种XML的配置文件外,还有.properties文件.
C3P0连接池工具类
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 C3P0Util {
// 创建C3P0连接池对象,内部村粗了多个Connection对象
// 创建对象时,会自动读取src根目录下的配置文件
private static ComboPooledDataSource cpds = new ComboPooledDataSource();
// 私有化构造器
private C3P0Util(){
}
// 定义静态方法,获取Connection对象
public static Connection getConnection() throws Exception{
return cpds.getConnection();
}
/**
* 获取连接池的方法
* @return
*/
public static DataSource getDataSource(){
return cpds;
}
public static void close(Statement stmt, Connection conn){
close(null, stmt, conn);
}
/**
* 释放资源
* @param rs
* @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();
}
}
}
}
Druid
使用步骤:
1. 导入jar包 druid-1.0.9.jar
2. 定义配置文件是properties
文件,可以叫任意名称,可以放在任意目录下
3. 加载配置文件properties
4. 获取数据库连接池对象,通过工厂类来获取DruidDataSourceFactory
5. 获取连接 getConnection
/*
druid演示
*/
public class DruidDemo {
public static void main(String[] args) throws Exception {
//1. 导入jar包
//2. 定义配置文件
//3. 加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//4. 获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//5. 获取连接
Connection conn = ds.getConnection();
System.out.println(conn);
}
}
Druid连接池工具类
/**
* Druid连接池工具类
*/
public class JDBCUtils {
//1. 定义成员变量DataSource
private static DataSource ds;
static{
try {
//1. 加载配置文件
Properties pro = new Properties();
pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
//2. 获取连接池DataSource对象
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e){
e.printStackTrace();
}
}
/**
* 获取连接的方法
* @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(Statement stmt, Connection conn){
close(null, stmt, conn);
}
/**
* 释放资源
* @param rs
* @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();
}
}
}
}
使用Druid工具类完成对关系表添加一条记录操作:
/**
* 使用新工具类, 做一个添加的操作
*/
public class DruidDemo2 {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
// 给account表添加一条记录
try {
//1. 获取连接
conn = JDBCUtils.getConnection();
//2. 定义sql
String sql = "INSERT INTO account values(null, ?, ?)";
//3. 获取pstmt对象
pstmt = conn.prepareStatement(sql);
//4. 给?赋值
pstmt.setString(1, "朝阳");
pstmt.setDouble(2, 3000);
//5. 执行sql语句
int count = pstmt.executeUpdate();
System.out.println(count);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 释放资源
JDBCUtils.close(pstmt, conn);
}
}
}
下一篇: JDBC C3P0 数据源配置