Java数据库连接池1——dbcp
主要内容
1、用纯java方式获取连接池
2、从配置文件中拿连接池
3、自己做一个dbcp的Utils,用于包装一个ThreadLocal
附录:所有要用到的工具包的链接
用纯java方式获取连接池
首先要导驱动包
public void demo1() {
// 纯JAVA方式使用dbcp连接池
// ds是我们以前自己做的pool
BasicDataSource ds = new BasicDataSource();
ds.setUsername("root");
ds.setPassword("1234");
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://127.0.0.1:3306/abc?useUnicode=true&characterEncoding=utf8");
// 需要就加ThreadLocal
try {
Connection con = ds.getConnection();
System.out.println("con:" + con);
System.out.println("-----以下演示dbcp属性-------");
System.out.println(ds.getDefaultAutoCommit());// true
System.out.println(ds.getMaxActive());// 同时可支持多少个链接
System.out.println(ds.getInitialSize());// 初始化个数
System.out.println(ds.getMaxIdle());// 最大空闲时间
System.out.println(ds.getMaxWait());// 最大等待时间
System.out.println("------以下演示从池中获取链接-------");
for (int i = 0; i < 10; i++) {
Connection conn = ds.getConnection();
System.out.println(conn.hashCode());
// 内存地址相同
//奇数就关闭
if (i % 2 == 1) {
conn.close();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
演示结果
在这里最大同时连接数为8,当它断开链接又重新从池里拿的时候,它不会重新创建,而是直接拿刚才断开的那个,从hashCode就能看出。
从配置文件中拿连接池
public void demo2() {
// 配置文件方式
Properties p = new Properties();
try {
/*
* 方式1:配置文件放置在bin目录中和 DbcpPoolDemo.class 文件一起的地方(不在src下)
* p.load(DbcpPoolDemo
* .class.getResourceAsStream("dbcp.properties"));
* 底层读取的是classpath(bin目录)下的资源,但是在开发时,我们通常把 资源文件放在src下,由编译器帮我们编译到bin
*/
// 方式2:配置文件的位置从classPath根目录的位置开始
p.load(DbcpPoolDemo.class.getClassLoader().getResourceAsStream(
"cn/hncu/dbcp/dbcp.properties"));
DataSource ds = BasicDataSourceFactory.createDataSource(p);
Connection con = ds.getConnection();
System.out.println(con);
} catch (Exception e) {
e.printStackTrace();
}
}
//配置文件中所有属性要和前面set一致 dbcp.properties
##MySQL
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql:///abc?useUnicode=true&characterEncoding=UTF-8
username=root
password=1234
自己做一个dbcp的Utils,用于包装一个ThreadLocal
public class DbcpUtils {
/*dbcp池 本身不含有 ThreadLocal功能,无法实现我们需要的同一线程共享同一con
因此我们会自己封装一个DbcpUtils
*/
private static DataSource ds ;//单例的池
private static ThreadLocal<Connection> t=new ThreadLocal<Connection>();
static{
Properties p = new Properties();
try {
p.load(DbcpUtils.class.getClassLoader().getResourceAsStream("cn/hncu/dbcp/dbcp.properties"));
ds = BasicDataSourceFactory.createDataSource(p);
/* 设置同时最大连接数
* BasicDataSource ds2 = (BasicDataSource) ds;
ds2.setMaxActive(10);
*/
} catch (Exception e) {
throw new RuntimeException("数据库连接池创建失败!");
}
}
//以后会用到这个功能 :
public static DataSource getDataSource(){
return ds;
}
public static Connection getConnection(){
Connection con = t.get();
if(con==null){
try {
con=ds.getConnection();
t.set(con);
} catch (SQLException e) {
e.printStackTrace();
}
}
return con;
}
public static void cleanConFromThradeLocal(){
t.set(null);
}
}
测试
public void demo3() throws Exception {
Connection con = DbcpUtils.getConnection();
System.out.println(con);
con.close();// 关闭以后就不能用了
// 在close() 之后 紧接着写一行 清空t 本地线程池中的con对象 如 t.set(null);
DbcpUtils.cleanConFromThradeLocal();
Connection conn = DbcpUtils.getConnection();
System.out.println(conn);
}
附录
连接池的工具包
http://pan.baidu.com/s/1hrQBXyO