需求:
传统JDBC的操作,对连接的对象销毁不是特别好.每次创建和销毁连接都是需要花费时间.可以使用连接池优化的程序.
* 在程序开始的时候,可以创建几个连接,将连接放入到连接池中.用户使用连接的时候,可以从连接池中进行获取.用完之后,可以将连接归还连接池.
技术分析:
* SUN公司提供了一个连接池的接口.(javax.sql.DataSource).
* 定义一个连接池:实现这个接口.
* 使用List集合存放多个连接的对象
自定义连接池的代码.
public class MyDataSource implements DataSource{
// 创建一个List集合用于存放多个连接对象.
private List<Connection> list = new ArrayList<Connection>();
// 在程序开始的时候,初始化几个连接,将连接存放到list中.
public MyDataSource() {
// 初始化3个连接:
for(int i=1;i<=3;i++){
Connection conn = JDBCUtils.getConnection();
list.add(conn);
}
}
@Override
// 获得连接的方法:
public Connection getConnection() throws SQLException {
if(list.size() <= 0){
for(int i=1;i<=3;i++){
Connection conn = JDBCUtils.getConnection();
list.add(conn);
}
}
Connection conn = list.remove(0);
return conn;
}
// 归还连接的方法:
public void addBack(Connection conn){
list.add(conn);
}
...
}
常见的开源的数据库连接池:
- DBCP:
DBCP(DataBase connection pool),数据库连接池。是 apache 上的一个 java 连接池项目,也是 tomcat 使用的连接池组件。单独使用dbcp需要2个包:commons-dbcp.jar,commons-pool.jar由于建立数据库连接是一个非常耗时耗资源的行为,所以通过连接池预先同数据库建立一些连接,放在内存中,应用程序需要建立数据库连接时直接到连接池中申请一个就行,用完后再放回去。
- C3P0:
C3P0是一个开源的JDBC连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。目前使用它的开源项目有Hibernate,Spring等。
- Tomcat内置连接池:
C3P0连接池的使用
第一步:引入C3P0连接池的jar包.
第二步:编写代码:
* 手动设置参数:
* 配置文件设置参数:
导包
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:///mysql</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">5</property>
<property name="maxPoolSize">20</property>
</default-config>
<named-config name="test">
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///test</property>
<property name="user">root</property>
<property name="password">root</property>
</named-config>
</c3p0-config>
ps:C3P0连接池的配置文件可以私藏一份欧!以后就不用写了<*-*>
C3P0工具类
public class DataSourceUtils {
private static DataSource dataSource = new ComboPooledDataSource();
private static ThreadLocal<Connection> tl = new ThreadLocal<Connection>();
// 直接可以获取一个连接池
public static DataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() throws SQLException{
return dataSource.getConnection();
}
// 获取连接对象
public static Connection getCurrentConnection() throws SQLException {
Connection con = tl.get();
if (con == null) {
con = dataSource.getConnection();
tl.set(con);
}
return con;
}
// 开启事务
public static void startTransaction() throws SQLException {
Connection con = getCurrentConnection();
if (con != null) {
con.setAutoCommit(false);
}
}
// 事务回滚
public static void rollback() throws SQLException {
Connection con = getCurrentConnection();
if (con != null) {
con.rollback();
}
}
// 提交并且 关闭资源及从ThreadLocall中释放
public static void commitAndRelease() throws SQLException {
Connection con = getCurrentConnection();
if (con != null) {
con.commit(); // 事务提交
con.close();// 关闭资源
tl.remove();// 从线程绑定中移除
}
}
// 关闭资源方法
public static void closeConnection() throws SQLException {
Connection con = getCurrentConnection();
if (con != null) {
con.close();
}
}
public static void closeStatement(Statement st) throws SQLException {
if (st != null) {
st.close();
}
}
public static void closeResultSet(ResultSet rs) throws SQLException {
if (rs != null) {
rs.close();
}
}
}
写一个增删改的测试类
public class TestC3P0 {
// 增加用户
@Test
public void adduser() {
try {
// 1.创建核心类QueryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写SQL语句
String sql = "insert into User values(?,?,?)";
// 3.为站位符设置值
Object[] params = { "4", "花花", 1000 };
// 4.执行添加操作
int rows = qr.update(sql, params);
if (rows > 0) {
System.out.println("添加成功!");
} else {
System.out.println("添加失败!");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 删除用户
@Test
public void deleteuser() {
try {
// 1.创建核心类QueryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写SQL语句
String sql = "delete from User where cid=?";
// 3.为站位符设置值
Object[] params = { "4" };
// 4.执行添加操作
int rows = qr.update(sql, params);
if (rows > 0) {
System.out.println("刪除成功!");
} else {
System.out.println("刪除失败!");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 修改用户
@Test
public void updateuser() {
try {
// 1.创建核心类QueryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写SQL语句
String sql = "update User set account=? where cid=?";
// 3.为站位符设置值
Object[] params = { 500, "2" };
// 4.执行添加操作
int rows = qr.update(sql, params);
if (rows > 0) {
System.out.println("修改成功!");
} else {
System.out.println("修改失败!");
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
结果:
添加成功!
修改成功!
刪除成功!
下面是查询的测试类
public class TestC3P0Select {
/*
* 查询所有用户方法
*/
@Test
public void testQueryAll() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from User";
// 3.执行查询操作
List<User> users = qr.query(sql, new BeanListHandler<User>(User.class));
// 4.对结果集集合进行遍历
for (User user : users) {
System.out.println(user.getCname() + " : " + user.getAccount());
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 根据id查询用户方法
*/
@Test
public void testQueryUserById() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from User where cid=?";
// 3.为占位符设置值
Object[] params = { "1" };
// 4.执行查询操作
User user = qr.query(sql, new BeanHandler<User>(User.class), params);
System.out.println(user.getCname() + " : " + user.getAccount());
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 根据所有用户的总个数
*/
@Test
public void testQueryCount() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select count(*) from User";
// 4.执行查询操作
Long count = (Long) qr.query(sql, new ScalarHandler());
System.out.println(count);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 查询所有用户方法
*/
@Test
public void testQueryAll1() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from User";
// 3.执行查询操作
List<Map<String, Object>> list = qr.query(sql, new MapListHandler());
// 4.对结果集集合进行遍历
for (Map<String, Object> map : list) {
System.out.println(map);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
/*
* 查询所有用户方法
*/
@Test
public void testQueryAll2() {
try {
// 1.获取核心类queryRunner
QueryRunner qr = new QueryRunner(DataSourceUtils.getDataSource());
// 2.编写sql语句
String sql = "select * from User";
// 3.执行查询操作
List<Object> list = qr.query(sql, new ColumnListHandler("cname"));
// 4.对结果集集合进行遍历
for (Object object : list) {
System.out.println(object);
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
结果:
{cname=tom, account=1000.0, cid=1}
{cname=joy, account=500.0, cid=2}
{cname=king, account=1000.0, cid=3}
tom
joy
king
3
tom : 1000.0
tom : 1000.0
joy : 500.0
king : 1000.0