JDBC数据库连接池
连接池的作用
- 在缓冲池中放入一定数量的连接,当有程序请求数据库连接时,只需要在缓冲池中取出一个连接,程序使用完毕后,再放入缓冲池
- 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
- 当程序访问量大过缓冲池中的连接时,这些请求将会加入到等待队列中,直到其他程序归还连接
C3P0连接池
将C3P0.config.xml 配置好后放入src目录下
//获取数据源("zyy"为配置文件的named-config name)
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("zyy");
//获取连接
Connection connection = comboPooledDataSource.getConnection();
Druid连接池
将druid.properties配置好后放入src目录下
//获取properties
Properties properties = new Properties();
//加载配置文件
properties.load(new FileInputStream("src\\druid.properties"));
//获得数据源
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
//获得连接
Connection connection = dataSource.getConnection();
遍历传统的result的问题
- 关闭Connection后,返回的result是不能使用的
- 结果集不利于数据管理【每次查询结果集都要遍历一次】
- 使用返回信息的方法意义不明【getXxx】
APJDBCUtils
commons-dbutils是Apache组织提供的一个开源JDBC工具类库,它是对JDBC的封装,使用dbutils能极大简化jdbc编码的工作量。
DbUtils类
- QueryRunner类:该类封装了SQL的执行,是线程安全的。可以实现增、删、改、查、批处理
- 使用QueryRunner类实现查询
- ResultSetHandler接口:该接口用于处理java.sql.ResultSet,将数据按要求转换为另一种形式
JavaBean(domain/pojo) : 表中有什么样的字段,JavaBean就有什么样的属性,提供get和set方法(必须提供无参构造)
ResultSetHandler 是 以下所有类的父类
类 | 作用 |
---|---|
ArrayHandler | 把结果集中的第一行数据转成对象数组。 |
ArrayListHandler | 把结果集中的每一行数据都转成一个数组,再存放到List中。 |
BeanHandler | 将结果集中的第一行数据封装到一个对应的JavaBean实例中。 |
BeanListHandler | 将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。 |
ColumnListHandler | 将结果集中某一列的数据存放到List中. |
KeyedHandler(name) | 将结果集中的每行数据都封装到Map里,再把这些map再存到一个map里,其key为指定的key. |
MapHandler | 将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。 |
MapListHandler | 将结果集中的每一行数据都封装到一个Map里,然后再存放到List |
ResultSetHandler | 将一个值封装成Object对象 |
方法 | 作用 |
---|---|
query(connection,sql,new ResultSetHandler(JavaBean.class),?1,?2…) | 查询 |
update(connection,sql ,?1,?2…) | DML |
查询多行数据
//获取连接
Connection connection = JDBCUtilsByDruid.getConnection();
//创建QueryRunner
QueryRunner queryRunner = new QueryRunner();
//编写sql语句
String sql = "select ? from admin";
//获得结果集
//BeanListHandler
//将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
List<Admin> lists = queryRunner.query(connection, sql, new BeanListHandler<>(Admin.class),"username");
//关闭连接
JDBCUtilsByDruid.close(null, null, connection);
//遍历结果集
for (Admin list : lists) {
System.out.println(list);
}
//(1) query方法就是执行sql 语句,得到resultset ---封装到 -->ArrayList集合中
//(2)返回集合
//(3)connection:连接
//(4)sql :执行的sql语句
//(5) new BeanListHandler<>(Actor.class):在将resultset -> Actor对象->封装到 ArrayListl/底层使用反射机制去获取Actor类的属性,然后进行封装
//(6)"username"就是给 sql语句中的?赋值,可以有多个值,因为是可变参数0bject. .. params
//(7〕底层得到的resultset,会关闭query、PreparedStatment
List<Admin> lists = queryRunner.query(connection, sql, new BeanListHandler<>(Admin.class),"username");
查询单个结果
//获取连接
Connection connection = JDBCUtilsByDruid.getConnection();
//创建QueryRunner
QueryRunner queryRunner = new QueryRunner();
//编写sql语句
String sql = "select * from admin where username = 'zyy'";
//返回一个对象
//BeanHandler
//将结果集中的第一行数据封装到一个对应的JavaBean实例中。
Admin query = queryRunner.query(connection, sql, new BeanHandler<Admin>(Admin.class));
System.out.println(query);
查询结果单行单列
//获取连接
Connection connection = JDBCUtilsByDruid.getConnection();
//创建queryRunner
QueryRunner queryRunner = new QueryRunner();
//编写sql语句
String sql = "select password from admin where username = 'zyy'";
//获得Object对象
//ScalarHandler
//将一个值封装成Object对象返回
Object query = queryRunner.query(connection, sql, new ScalarHandler());
System.out.println(query);
DML语句
//获得连接
Connection connection = JDBCUtilsByDruid.getConnection();
//创建QueryRunner
QueryRunner queryRunner = new QueryRunner();
//编写sql语句
String sql = "insert into admin values(?,?)";
//返回受影响的函数
int rows = queryRunner.update(connection, sql, "张三", "123");
System.out.println(rows > 0 ? "成功":"失败");
//关闭连接
JDBCUtilsByDruid.close(null,null,connection);
数据库连接池
传统获取Connection问题
- 每次与数据库连接,都要向数据库进行请求,频繁的操作会占用很多的系统资源,容易造成服务器崩溃。
- 程序使用数据库过后,必须断开与数据库的连接,如果程序发生异常,那么将会造成数据库的内存泄露,最终导致重启数据库
- 传统获取连接方式,是不能控制创建的连接数量,如果连接过多(没有缓冲机制),也可能导致内存泄露,数据库崩溃
数据库连接池
- 在缓冲池中放入一定数量的连接,当有程序请求数据库连接时,只需要在缓冲池中取出一个连接,程序使用完毕后,再放入缓冲池
- 数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
- 当程序访问量大过缓冲池中的连接时,这些请求将会加入到等待队列中,直到其他程序归还连接
数据库连接池类型
C3P0连接池第一种连接方式
准备工作
将C3P0 jar包放入到libs目录下
引入到项目中
1.创建数据源对象
2.给数据源设置相关的参数
3.设置初始连接数和最大连接数
4.获得Connection
C3P0连接池第二种连接方式(推荐)
使用配置文件模板来进行操作
将C3P0提供的配置文件C3P0.config.xml放入到src目录下
根据配置文件的信息,修改对应的参数即可
数据源名称
数据库地址
用户名和密码
初始连接数、最小连接数、最大连接数…
…
Druid(德鲁伊)连接池
使用Druid
准备工作
1.将druid jar包放入到libs目录中
2.加入到项目中
3.将druid 模板(配置文件)放入到src下
使用druid连接池
Druid工具类
初始化Druid
获取Connection
返回到缓冲池中
package com.study.jdbc.Utils;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* @author 珀筱
*/
@SuppressWarnings({"all"})
public class JDBCUtilsByDruid {
private static DataSource dataSource;
static {
Properties properties = new Properties();
try {
properties.load(new FileInputStream("src\\druid.properties"));
dataSource = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
//关闭连接,在数据库连接池中,close不是关闭连接
//而是把使用的Connection放回到缓冲池中
public static void close(ResultSet resultSet, Statement statement, Connection connection) {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
APJDBCUtils
APJDBCUtils 运行逻辑
土方法完成封装
APJDBCUtils 使用
引入dbutils jar包到libs目录下
加入到项目中
使用 APJDBCUtils
查询单个结果
不存在返回null
查询结果为单行单列
不存在返回null
DML语句
表和JavaBean之间的映射关系
Basic-DAO
DAO
属性
通用DML方法
查询结果多条语句
查询结果单个对象
查询结果单行单列
表DAO