连接池
什么是连接池
对于单用户程序,整个程序运行期间使用一个Connection对象,但对于多用户程序,使用一个Connection对象使用效率就很低,若为每一个对象都创建一个连接,会增加服务器的负担。所以就有了一个连接池,像一个“容器”,程序启动时,先缓存一些Connection,有用户需要
,就取出一个供其使用,使用完成后,在将Connection对象归还到“容器”中。连接池里的Connection对象可以重复使用,从而提高程序的运行效率。连接池是面向多用户连接数据库的程序。
- 常用的连接池
- DBCP连接池:Apache公司的
- C3P0连接池:免费,开源。在长时间运行的情况下,C3p0内部的资源释放方便的功能要比DBCP要强大。Spring、Hibernate框架 使用了这个连接池。
DBCP连接池的使用
1、不使用配置文件(硬配置)
第三方jar包:
commons-dbcp-1.4.jar
commons-pool-1.6.jar
- 创建DBCP连接池对象(BasicDataSource)
给DBCP连接池传递连接参数
dataSource.setDriverClassName(“com.mysql.jdbc.Driver”);
dataSource.setUrl(“jdbc:mysql://127.0.0.1:3306/test1”);
dataSource.setUsername(“root”);
dataSource.setPassword(“123”);获取Connection对象
- 获取SQL执行器
- 释放资源
2、使用配置文件
- 读取配置文件(Properties类)
- 创建DBCP连接池对象
- 获取Connection对象
- 获取SQL执行器
- 释放资源
关键代码
import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
java.sql.ResultSet;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
public class Demo {
public static void main(String[] args) throws Exception {
//读取配置文件
Properties pro=new Properties();
//获取类加载器,自动创建一个这个文件资源的文件输入流
pro.load(Demo.class.getClassLoader().getResourceAsStream("a.properties"));
//创建DBCP连接池对象
DataSource dataSource = BasicDataSourceFactory.createDataSource(pro);
//获取连接
Connection con = dataSource.getConnection();
//获取SQL执行器
String sql="select * from user";
PreparedStatement pstmt = con.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery();
while(rs.next()){
System.out.println(rs.getString("name"));
}
con.close();
}
配置信息(a.properties)
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db_demo
username=root
password=123456
C3P0连接池的使用
所需第三方jar包:
c3p0-0.9.2-pre5.jar
mchange-commons-java-0.2.3.jar
1. 将C3P0的配置文件:c3p0-config.xml复制到项目的src目录下
1. 文件名不能更改
2. 必须放在src目录下
3. 默认配置()和命名配置()
使用步骤
- 创建连接池对象(ComboPooledDataSource)
- 利用连接池对象获取数据库连接对象
- 获取sql执行器
- 释放资源
DBUtils工具包
是一个第三方的工具包,内部封装类大量数据库操作的方法。使用它时,需要的连接池C3P0的jar包。
- 核心类
- QueryRunner(类):负责执行SQL语句。相当于Statement,执行查询时,可以将查询结果自动封装成各种类型的结果集对象
- ResultSetHandler(接口):当使用QueryRunner执行查询时,可以通过ResultSetHandler的某一个子类来告知QueryRunner怎样封装结果集。
QueryRunner 类里的核心方法(增 删 改 查 CUID)
创建QueryRunner对象:构造时需要一个连接池对象
QueryRunner qr = new QueryRunner(new ComboPooledDataSource());
public int update(String sql,Object ... params):用于执行添加、修改、删除语句
public 返回值类型 query(String sql,ResultSetHandler rsh,Object ... params):用于执行查询。
ResultSetHandler接口
ResultSetHandler的子类
BeanHandler: 用于查询一条记录,如果查询的是多天,也只能返回一条记录。返回的查询结果是封装的某个JavaBean对象。
String sql = "select * from user where id = ?"; User user = qr.query(sql, new BeanHandler<User>(User.class), 8); System.out.println(user);
BeanListHandler: 用于查询多条记录。每条记录封装一个JavaBean对象,多个JavaBean封装到一个List中
String sql = "select * from user"; List<User> userList = qr.query(sql, new BeanListHandler<User>(User.class)); for(User u : userList){ System.out.println(u); }
ScalarHandler:用于查询单结果。例如聚合函数查询。
String sql = "select count(id) from user"; Object obj = qr.query(sql, new ScalarHandler()); System.out.println("结果:" + obj + " 类型:" + obj.getClass().getName());
Object[] ArrayHandler:用于查询一条记录,将每个字段的值封装一个Object对象,将所有列的Object对象封装到一个Object[]数组中返回。可以用于多表连接查询
String sql = "select * from user u,user_role ur,role r where u.id = ur.user_id and ur.role_id = r.id and u.id = 1"; Object[] objArray = qr.query(sql, new ArrayHandler()); for(Object o : objArray){ System.out.print(o + "\t"); } System.out.println();
-List< Object[] > ArrayListHandler: 用于查询多条记录。每条记录封装一个Object[]数组,多个Object[]数组封装到一个List集合中.可以用于多表连接查询
String sql = “select * from user u,user_role ur,role r where u.id = ur.user_id and ur.role_id = r.id”;
List< Object[] > objList = qr.query(sql, new ArrayListHandler());
for(Object[] objArray : objList){
System.out.println(Arrays.toString(objArray));
}