JDBC连接池
概述
Connection对象一次性使用的创建和销毁耗时。
连接池可以让连接得到复用, 避免浪费。
程序初始化的时候,初始化多个连接,将多个连接放入到池(集合)中.每次获取的时候,都可以直接从连接池中进行获取.使用结束以后,将连接归还到池中。
原理
- 程序一开始就在连接池创建一定数量的连接
- 使用的时候直接取连接对象, 用完归还
- 如果池子里面的连接使用完了, 还有程序需要使用连接, 先等待一段时间,如果在这段时间之内有连接归还, 就拿去使用; 如果还没有连接归还, 新创建一个, 但是用完就毁
- 集合选择LinkedList
增删比较快
LinkedList里面的removeFirst()和addLast()方法和连接池的原理吻合
第三方连接池
我们所定义的连接池和第三方的连接池相比,还是显得弱鸡。使用第三方工具需要导入jar包,有些还要导入配置文件。
• C3P0连接池,它实现了数据源和JNDI绑定,支持JDBC3规范和JDBC2的标准扩展。C3P0是异步操作的,所以一些操作时间过长的JDBC通过其它的辅助线程完成。目前使用它的开源项目有Hibernate,Spring等。C3P0有自动回收空闲连接功能
• 德鲁伊druid连接池:阿里巴巴开源平台的一个项目,整个项目由数据库连接池、插件框架和SQL解析器组成。
• DBCP(DataBase Connection Pool)数据库连接池,是Apache上的一个Java连接池项目,也是Tomcat使用的连接池组件。dbcp没有自动回收空闲连接的功能。
datasource接口
概述
javax.sql.DataSource,数据库连接池公共的接口,其实就是连接池,可以获得Connection连接对象。各个数据库厂商提供了实现。
缺点
DataSource中并没有提供归还连接的方法,解决方法:
1、继承。
条件:可以控制父类, 最起码知道父类的名字
2、装饰者模式。
1. 创建一个MyConnection实现Connection
2. 在MyConnection得到被增强的connection对象
3. 改写MyConnection里面的close()方法的逻辑为归还
4. MyConnection里面的其它方法 调用被增强的connection对象之前的逻辑
5. 在MyDataSource03的getConnection()方法里面 返回了myConnection
3、动态代理。
示例
public class MyDataSource2 implements DataSource{
private LinkedList<Connection> connectionPool = new LinkedList<>();
public MyDataSource2() {
for (int i = 0; i < 5; i++) {
try {
Connection conn = DriverManager.getConnection("jdbc:mysql:///day20?characterEncoding=utf8", "root", "123");
connectionPool.add(conn);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
@Override
public Connection getConnection() throws SQLException {
//如果容器中有连接,则从容器中获取,如果容器中没有连接,就直接新创建连接
Connection conn = null;
if (connectionPool.size() > 0){
conn = connectionPool.removeFirst();
}else {
conn = DriverManager.getConnection("jdbc:mysql:///day20?characterEncoding=utf8", "root", "123");
}
return conn;
}
C3P0连接池
概述
开源的JDBC连接池。能自动回收空闲连接。
要求
1、导入c3p0-0.9.1.2.jar到lib
2、导配置文件c3p0-config.xml
配置信息
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql:///10_周宇科_课设_书店?characterEncoding=UTF-8&useUnicode=true</property>
<property name="user">root</property>
<property name="password">root</property>
<property name="initialPoolSize">5</property>
</default-config>
</c3p0-config>
步骤
- 拷贝jar
- 拷贝配置文件(c3p0-config.xml)到src目录的resources【名字不要改】
- 创建C3P0连接池对象(会自动读取resources目录下的c3p0-config.xml,所以不需要我们解析配置文件) DataSource ds = new ComboPooledDataSource();
- 从池子里面获得连接
工具类
工具类,提供DataSource对象,保证整个项目只有一个DataSource对象
public class C3P0Util {
private static DataSource dataSource;
static {
dataSource = new ComboPooledDataSource();
}
public static DataSource getDataSource(){
return dataSource;
}
}
DRUID连接池
概述
阿里巴巴开发的号称为监控而生的数据库连接池,是国内目前性能最好的数据库连接池。
要求
导入druid-1.0.9.jar
导配置文件druid.properties
步骤
1. 导入DRUID jar包
2. 拷贝配置文件到src目录的resources中
3. 根据配置文件创建Druid连接池对象
4. 从Druid连接池对象获得Connection
实现
1、创建druid.properties, 放在src目录下,编辑好内容
url=jdbc:mysql:///day20
username=root
password=123
driverClassName=com.mysql.jdbc.Driver
2、编写Java代码
Properties properties = new Properties();
// 关联druid.properties文件
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
Connection connection = dataSource.getConnection();
写个工具类
public class DruidUtil {
private static DataSource dataSource;
static {
try {
Properties properties = new Properties();
InputStream is = DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//druid底层是使用的工厂设计模式,去加载配置文件,创建DruidDataSource对象
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static DataSource getDataSource(){
return dataSource;
}
}
DBUtils数据库工具jar包
概述
对JDBC进行简单封装的开源工具类库,能简化开发,同时也不会影响程序的性能
步骤
- 拷贝commons-dbutils-1.4.jar包
- 创建QueryRunner()对象,传入dataSource
- 调用update()方法
方法
1、创建QueryRunner对象
new QueryRunner(DataSource ds) 提供连接池,DBUtils底层自动维护连接connection
2.1、执行增删改的SQL语句
int update(String sql, Object… params) 执行增删改的SQL语句, params参数就是可变参数,参数个数取决于语句中问号的个数
2.2、执行查询的SQL语句
query(String sql, ResultSetHandler<T> rsh, Object... params) 其中ResultSetHandler是一个接口,代表结果集处理者。
- BeanHandler() 查询一条记录封装到JavaBean对象
- BeanListHandler() 查询多条记录封装到List<JavaBean> list
- MapHandler() 查询一条记录封装到Map对象
- MapListHandler() 查询多条记录封装到List<Map> list
- ScalarHandler() 封装单个记录的 eg:统计数量
封装到JavaBean条件, 查询出来的数据的列名必须和JavaBean属性一致
示例
增删改:String sql = "insert into user values (null,?,?,?)";
//1. 创建QueryRunner对象
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
//2. 使用QueryRunner对象调用update(sql,...)执行增删改的SQL语句
queryRunner.update(sql,"aobama","666666","圣枪游侠");
查多条:String sql = "select * from user where id>?";
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
List<Map<String, Object>> mapList = queryRunner.query(sql, new MapListHandler(), 1);
for (Map<String, Object> map : mapList) {
System.out.println(map);
}
查一行:String sql = "select * from user where id=?";
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
//执行SQL语句
U user = queryRunner.query(sql, new BeanHandler<>(U.class), 3);
System.out.println(user);
查一个:String sql = "select count(*) from user";
QueryRunner queryRunner = new QueryRunner(DruidUtil.getDataSource());
//需要用long接收,因为你格局得大一点
long count = (long) queryRunner.query(sql,new ScalarHandler());
System.out.println(count);
以上就是笔者的连接池和DBUtils包的笔记了,水平局限略略略,但希望能帮到你,喵~
转载请注明出处,谢谢!