为什么要把连接的数据库对象放到threadlocal线程池中?
在用户进行数据库访问的时候,我们应该限制他们来对数据库的连接获取个数,应该没人仅限一个,这样可以减轻服务器的负担,并且这种方式能够让其他对象来对数据库进行事务操作时,不用辨别是哪种对象,因为该对象只有一个
如何通过连接c3p0数据库连接池获得数据库连接:
首先需要c3p0的jar包以及c3p0的配置文件
配置文件的代码如下:
<c3p0-config>
<!-- 默认配置,如果没有指定则使用这个配置 -->
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">
<![CDATA[jdbc:mysql://127.0.0.1:3306/luojuan?useUnicode=true&characterEncoding=UTF-8]]>
</property>
<property name="user">root</property>
<property name="password">1234</property>
<!-- 初始化池大小 -->
<property name="initialPoolSize">2</property>
<!-- 最大空闲时间 -->
<property name="maxIdleTime">30</property>
<!-- 最多有多少个连接 -->
<property name="maxPoolSize">10</property>
<!-- 最少几个连接 -->
<property name="minPoolSize">2</property>
<!-- 每次最多可以执行多少个批处理语句 -->
<property name="maxStatements">50</property>
</default-config>
<!-- 命名的配置 -->
<named-config name="hncu">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/luojuan</property>
<property name="user">root</property>
<property name="password">1234</property>
<property name="acquireIncrement">5</property><!-- 如果池中数据连接不够时一次增长多少个 -->
<property name="initialPoolSize">100</property>
<property name="minPoolSize">50</property>
<property name="maxPoolSize">1000</property>
<property name="maxStatements">0</property>
<property name="maxStatementsPerConnection">5</property> <!-- he's important, but there's only one of him -->
</named-config>
</c3p0-config>
通过ComboPooledDataSource ds = new ComboPooledDataSource();得到ComboPooledDataSource对象
这个对象在构造时会自动去寻找读取你的配置文件
然后通过Connection con = ds.getConnection();就可以获得数据库的连接
现在需要通过单例的方式来把得到的连接放到threadlocal线程池中
package cn.hncu.dbutils;
import java.sql.Connection;
import javax.sql.DataSource;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class dbutilsC3po {
private static DataSource ds;// 单例的池
private static ThreadLocal<Connection> t = new ThreadLocal<Connection>();
static {
try {
ds = new ComboPooledDataSource();
} catch (Exception e) {
throw new RuntimeException("数据库连接池创建失败", e);
}
}
// 以后会用到这个功能
public static DataSource getDataSource() {
return ds;
}
public static Connection getcon() throws Exception {
Connection con = t.get();
if (con == null) {//如果没有连接对象为空我们就去获得一个然后存到t中
con = ds.getConnection();
t.set(con);
}
return con;
}
public static void clearconFromThreadlocal() {//在用户事务处理完毕进行con.close()方法调用时,需要调用这个方法将线程池清空,不然下一次还是拿的该连接,进行操作就会挂
t.set(null);
}
}
采用DButils来对数据库进行操作
package cn.hncu.dbutils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.MapListHandler;
import org.junit.Test;
import cn.hncu.domain.stud;
//queryrunner 用于执行sql
//resultsethandler 用于封装返回结果 具体使用时 是用他的实现类
public class DbUtilsDemo {
@Test
public void query0_DbUtilsHello_Demo() throws Exception {
QueryRunner run = new QueryRunner(dbutilsC3po.getDataSource());
List<Map<String, Object>> stud = run.query("select * from stud2",
new MapListHandler());
System.out.println(stud);
}
}