1、为什么要使用数据库连接池?
数据库(Connection)是一种关键的、有限的、昂贵的资源。
普通的JDBC数据库连接使用 DriverManager.getConnection(...)来获取,每次向数据库建立连接时都要将Conneciton加载到内存,在验证用户名和密码,使用完毕时,释放资源,即断开与数据库的连接。连接过多时,会导致内存泄漏,服务器崩溃。
所以,数据库的连接来之不易,保证重复使用,
2、使用连接池的好处
连接复用:通过建立一个数据库连接池以及一套连接使用管理策略,使得一个数据库连接可以得到高效、安全的复用,避免了数据库连接频繁建立、关闭的开销。
共享资源:连接池的使用解决了资源频繁分配、释放所造成的问题的。提供一套高效的连接分配、使用策略,最终目标是实现连接的高效、安全的复用。
3、常用连接池
DBCP(DataBase Connection Pool)属于Apache顶级项目Commons中的核心子项目
Druid:阿里开源的Druid(德鲁伊)不仅仅是一个连接池,还添加了监控功能等,号称世界上最好的连接池组件,非常受恩宠。
参考文章:
常用Java数据库连接池
数据库连接池了解和常用连接池对比
4、Java中如何使用连接池/数据源?
在Java中,连接池使用 javax.sql.DataSource接口来表示连接池(数据源)。
连接池:用池来管理Connection,这样可以重复使用Connection。连接池会自己创建Connection,使用时通过池来获取Connection对象,当使用完后再将Connection归还到池中去。池就可以再利用这个Connection。
数据源(DataSource)和连接池(Connection Pool)是同一个概念,好比对象和实例。
注意:DataSource和JDBC一样,仅仅只是接口,需要第三方组织来实现。
-
-
Connection
getConnection()
尝试建立与此
DataSource
对象所代表的数据源的连接。Connection
getConnection(String username, String password)
尝试建立与该
DataSource
对象所代表的数据源的连接。
-
需要导入这几个架包:注意JDK版本
commons-dbcp2-2.7.0.jar 官网下载与文档
commons-pool2-2.7.0.jar 官网下载
commons-logging-1.2.jar 官网下载
如何创建DataSource对象,参考文档:commons-dbcp2-2.7.0-src\doc\BasicDataSourceExample.java
1、简单测试
org.apache.commons.dbcp2.BasicDataSource类
BasicDataSource类实现了DataSource接口,可以用于DBCP连接池的简单使用。包含连接数据库的四要素等属性配置信息。
更详细的信息可参考DBCP的官
username要传递给JDBC驱动程序以建立连接的连接用户名。password要传递给JDBC驱动程序以建立连接的连接密码。url要传递给JDBC驱动程序以建立连接的连接URL。driverClassName要使用的JDBC驱动程序的标准Java类名。 参数默认描述INITIALSIZE0池启动时创建的初始连接数。 自:1.2maxTotal8可以同时从此池分配的最大活动连接数,或者无限制的负数。maxidle8池中可以保持空闲的最大连接数,没有额外的连接被释放,或者没有限制为负。minIdle0池中可以保持空闲的最小连接数,不创建额外的连接数,或者为零创建无连接数。maxWaitMillis无限期池将在抛出异常之前返回的连接等待(当没有可用连接时)的最大毫秒数,或-1无限期等待的毫秒数。import java.sql.Connection;
import java.sql.PreparedStatement;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSource;
import org.junit.Test;
public class DBCPTest {
public static DataSource getDataSource(){
BasicDataSource ds = new BasicDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/jdbcdemo");
ds.setUsername("root");
ds.setPassword("123456");
ds.setMaxTotal(5);
System.out.println(ds);
return ds;
}
@Test
public void testSave() throws Exception {
String sql = "INSERT INTO t_user(username,age) VALUES(?,?)";
Connection conn = null;
PreparedStatement ps = null;
// 从连接池中获取Connection对象
conn = getDataSource().getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1,"赵子龙");
ps.setInt(2,17);
ps.executeUpdate();
}
}
2、提取properties文件
org.apache.commons.dbcp2.BasicDataSourceFactory类
BasicDataSourceFactory实现了javax.naming.spi.ObjectFactory接口。
BasicDataSourceDataFactory类主要根据一个实现了DataSource接口的对象,获取该对象的相关数据源配置参数(通过Reference对象,采用类似指针的方法),然后将new一个BaiscDataSource对象,结合获取的参数,形成一个BasicDataSource对象,并将之返回。
dbcp.properties
#dbcp属性配置
#key不可以乱写,必须是BasicDataSource的属性 (setter方法)
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcdemo
username=root
password=123456
maxTotal=5
DBCPUtil.java
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp2.BasicDataSourceFactory;
// JDBC的工具类
public class DBCPUtil {
private static DataSource ds = null;
static{
try {
//加载读取dbcp.properties文件
Properties properties = new Properties();
InputStream inStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("dbcp.properties");
properties.load(inStream);
System.out.println(properties.getProperty("url"));
//创建DataSource对象
ds = BasicDataSourceFactory.createDataSource(properties);
}catch (Exception e){
e.printStackTrace();
}
}
// 从连接池中获取Connection对象
public static Connection getConnection(){
try {
return ds.getConnection();
}catch (Exception e){
e.printStackTrace();
}
return null;
}
//释放资源,不断开与数据库的连接,资源归还给连接池管理
public static void close(Connection conn, Statement st, ResultSet rs){
try {
if(rs != null){
rs.close();
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(st != null){
st.close();
}
}catch (Exception e){
e.printStackTrace();
}finally {
try {
if(conn != null){
conn.close();
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
}
DBCPTest.java
import java.sql.Connection;
import java.sql.PreparedStatement;
import org.junit.Test;
import cn.jq.jdbc.util.DBCPUtil;
public class DBCPTest {
@Test
public void testSave2() {
String sql = "INSERT INTO t_user(username,age) VALUES(?,?)";
Connection conn = null;
PreparedStatement ps = null;
try {
// 从连接池中获取Connection对象
conn = DBCPUtil.getConnection();
ps = conn.prepareStatement(sql);
ps.setString(1,"赵子龙");
ps.setInt(2,17);
ps.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
} finally {
DBCPUtil.close(conn, ps, null);
}
}
}
三、Druid连接池
Druid(德鲁伊)了解:阿里巴巴开源项目 Druid 负责人温少访谈
Druid是一个开源项目,源码托管在github上,源代码仓库地址是 https://github.com/alibaba/druid 。同时每次Druid发布正式版本和快照的时候,都会把源码打包,你可以从上面的下载地址中找到相关版本的源码。Druid中文文档
使用起来类似于DBCP,导包 druid-1.1.11.jar
DruidDataSource的配置是兼容DBCP的。从DBCP迁移到DruidDataSource,只需要修改数据源的实现类就可以了。
DBCP的数据库连接池的实现是:
org.apache.commons.dbcp.BasicDataSource 替换为:com.alibaba.druid.pool.DruidDataSource
在上面demo修改DBCPUtil.java即可
如果需要使用Druid的其他配置,可以参考中文文档。
总结:
1)JDBC连接池只需要将DriverManager替换为DataSource来获取Connection即可
2)第三方组织实现DataSource接口的实现类来封装连接配置属性信息,具体查看官方文档。
3)提取xxx.properties文件,重构util时,使用 XxxDataSourceFactory类来创建DataSource。
简单入门,为后面掌握框架整合打好基础
站在前辈的肩膀上,每天进步一点点
ends~