使用代码实现Druid(德鲁伊)数据库连接池
Druid_.java
package jdbc.datasource;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.jupiter.api.Test;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
/**
* druid 的使用
*/
@SuppressWarnings({"all"})
public class Druid_ {
@Test
public void testDruid() throws Exception {
// 1. 加入 Druid jar 包
// 2. 加入 配置文件 druid.properties, 将该文件拷贝项目的 src 目录
// 3. 创建 Properties 对象, 读取配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src\\druid.properties"));
// 4. 创建一个指定参数的数据库连接池, Druid 连接
DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
long start = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
Connection connection = dataSource.getConnection();
// System.out.println(connection.getClass()); // class com.alibaba.druid.pool.DruidPooledConnection
// System.out.println("连接成功!");
connection.close();
}
long end = System.currentTimeMillis();
// druid 连接池 操作 500000 耗时=561
System.out.println("druid 连接池 操作 500000 耗时=" + (end - start));
}
}
druid.properties
#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/user_db?rewriteBatchedStatements=true
username=root
password=root
#initial connection Size
initialSize=10
#min idle connecton size
minIdle=5
#max active connection size
maxActive=50
#max wait time (5000 mil seconds)
maxWait=5000
通过德鲁伊数据库连接池获取连接对象
JDBCUtilsByDruid.java
package jdbc.datasource;
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;
/**
* 基于 druid 数据库连接池的工具类
*/
@SuppressWarnings({"all"})
public class JDBCUtilsByDruid {
private static DataSource ds;
// 在静态代码块完成 ds 初始化
static {
Properties properties = new Properties();
try {
properties.load(new FileInputStream("src\\druid.properties"));
ds = DruidDataSourceFactory.createDataSource(properties);
} catch (Exception e) {
e.printStackTrace();
}
}
// 编写 getConnection 方法
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
// 关闭连接, 再次强调: 在数据库连接池技术中, 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);
}
}
}
JDBCUtilsByDruid_USE.java
package jdbc.datasource;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
@SuppressWarnings({"all"})
public class JDBCUtilsByDruid_USE {
public static void main(String[] args) {
System.out.println(new JDBCUtilsByDruid_USE().testSelectToArrayList());
}
@Test
public void testSelect() {
System.out.println("使用 druid 方式完成");
// 1. 得到连接
Connection connection = null;
// 2. 组织一个 sql
String sql = "select * from actor where id >= ?";
PreparedStatement preparedStatement = null;
ResultSet set = null;
// 3. 创建 PreparedStatement 对象
try {
connection = JDBCUtilsByDruid.getConnection();
System.out.println(connection.getClass()); // 运行类型 com.alibaba.druid.pool.DruidPooledConnection
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1);//给?号赋值
// 执行, 得到结果集
set = preparedStatement.executeQuery();
// 遍历该结果集
while (set.next()) {
int id = set.getInt("id");
String name = set.getString("name"); // getName()
String sex = set.getString("sex"); // getSex()
Date borndate = set.getDate("borndate");
String phone = set.getString("phone");
System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
JDBCUtilsByDruid.close(set, preparedStatement, connection);
}
}
// 使用土方法来解决 ResultSet =封装=> Arraylist
@Test
public ArrayList<Actor> testSelectToArrayList() {
System.out.println("使用 druid 方式完成");
// 1. 得到连接
Connection connection = null;
// 2. 组织一个 sql
String sql = "select * from actor where id >= ?";
PreparedStatement preparedStatement = null;
ResultSet set = null;
ArrayList<Actor> list = new ArrayList<>(); // 创建 ArrayList 对象,存放 actor 对象
// 3. 创建 PreparedStatement 对象
try {
connection = JDBCUtilsByDruid.getConnection();
System.out.println(connection.getClass()); // 运行类型 com.alibaba.druid.pool.DruidPooledConnection
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1); // 给?号赋值
//执行, 得到结果集
set = preparedStatement.executeQuery();
// 遍历该结果集
while (set.next()) {
int id = set.getInt("id");
String name = set.getString("name");//getName()
String sex = set.getString("sex");//getSex()
Date borndate = set.getDate("borndate");
String phone = set.getString("phone");
// 把得到的 resultset 的记录, 封装到 Actor 对象, 放入到 list 集合
list.add(new Actor(id, name, sex, borndate, phone));
}
System.out.println("list 集合数据=" + list);
for (Actor actor : list) {
System.out.println("id=" + actor.getId() + "\t" + actor.getName());
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
JDBCUtilsByDruid.close(set, preparedStatement, connection);
}
// 因为 ArrayList 和 connection 没有任何关联,所以该集合可以复用.
return list;
}
}
Actor.java
package jdbc.datasource;
import java.util.Date;
public class Actor { // Javabean, POJO, Domain对象
private Integer id;
private String name;
private String sex;
private Date borndate;
private String phone;
public Actor() { // 一定要给一个无参构造器[反射需要]
}
public Actor(Integer id, String name, String sex, Date borndate, String phone) {
this.id = id;
this.name = name;
this.sex = sex;
this.borndate = borndate;
this.phone = phone;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBorndate() {
return borndate;
}
public void setBorndate(Date borndate) {
this.borndate = borndate;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
@Override
public String toString() {
return "\nActor{" +
"id=" + id +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", borndate=" + borndate +
", phone='" + phone + '\'' +
'}';
}
}
- 关闭connection 后,resultSet 结果集无法使用
- resultSet 不利于数据的管理
// 使用土方法来解决 ResultSet =封装=> Arraylist
@Test
public ArrayList<Actor> testSelectToArrayList() {
System.out.println("使用 druid 方式完成");
// 1. 得到连接
Connection connection = null;
// 2. 组织一个 sql
String sql = "select * from actor where id >= ?";
PreparedStatement preparedStatement = null;
ResultSet set = null;
ArrayList<Actor> list = new ArrayList<>(); // 创建 ArrayList 对象,存放 actor 对象
// 3. 创建 PreparedStatement 对象
try {
connection = JDBCUtilsByDruid.getConnection();
System.out.println(connection.getClass()); // 运行类型 com.alibaba.druid.pool.DruidPooledConnection
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1); // 给?号赋值
//执行, 得到结果集
set = preparedStatement.executeQuery();
// 遍历该结果集
while (set.next()) {
int id = set.getInt("id");
String name = set.getString("name");//getName()
String sex = set.getString("sex");//getSex()
Date borndate = set.getDate("borndate");
String phone = set.getString("phone");
// 把得到的 resultset 的记录, 封装到 Actor 对象, 放入到 list 集合
list.add(new Actor(id, name, sex, borndate, phone));
}
System.out.println("list 集合数据=" + list);
for (Actor actor : list) {
System.out.println("id=" + actor.getId() + "\t" + actor.getName());
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 关闭资源
JDBCUtilsByDruid.close(set, preparedStatement, connection);
}
// 因为 ArrayList 和 connection 没有任何关联,所以该集合可以复用.
return list;
}
package jdbc.datasource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.apache.commons.dbutils.handlers.ScalarHandler;
import org.junit.jupiter.api.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
@SuppressWarnings({"all"})
public class DBUtils_USE {
// 使用apache-DBUtils 工具类 + druid 完成对表的crud操作
@Test
public void testQueryMany() throws SQLException { // 返回结果是多行的情况
// 1. 得到 连接 (druid)
Connection connection = JDBCUtilsByDruid.getConnection();
// 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
// 3. 创建 QueryRunner
QueryRunner queryRunner = new QueryRunner();
// 4. 就可以执行相关的方法, 返回ArrayList 结果集
// String sql = "select * from actor where id >= ?";
// 注意: sql 语句也可以查询部分列
String sql = "select id, name from actor where id >= ?";
// 解读
// (1) query 方法就是执行sql 语句, 得到resultset ---封装到 --> ArrayList 集合中
// (2) 返回集合
// (3) connection: 连接
// (4) sql : 执行的sql语句
// (5) new BeanListHandler<>(Actor.class): 在将resultset -> Actor 对象 -> 封装到 ArrayList
// 底层使用反射机制 去获取Actor 类的属性,然后进行封装
// (6) 1 就是给 sql 语句中的? 赋值,可以有多个值,因为是可变参数Object... params
// (7) 底层得到的resultset ,会在query 关闭, 关闭PreparedStatment
/**
* 分析 queryRunner.query方法:
* public T query(Connection conn, String sql, ResultSetHandler rsh, Object... params) throws SQLException {
* PreparedStatement stmt = null;//定义PreparedStatement
* ResultSet rs = null;//接收返回的 ResultSet
* Object result = null;//返回ArrayList
*
* try {
* stmt = this.prepareStatement(conn, sql);//创建PreparedStatement
* this.fillStatement(stmt, params);//对sql 进行 ? 赋值
* rs = this.wrap(stmt.executeQuery());//执行sql,返回resultset
* result = rsh.handle(rs);//返回的resultset --> arrayList[result] [使用到反射,对传入class对象处理]
* } catch (SQLException var33) {
* this.rethrow(var33, sql, params);
* } finally {
* try {
* this.close(rs);//关闭resultset
* } finally {
* this.close((Statement)stmt);//关闭preparedstatement对象
* }
* }
*
* return result;
* }
*/
List<Actor> list = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
System.out.println("输出集合的信息");
for (Actor actor : list) {
System.out.print(actor);
}
//释放资源
JDBCUtilsByDruid.close(null, null, connection);
}
// apache-dbutils + druid 完成 返回的结果是单行记录(单个对象)
@Test
public void testQuerySingle() throws SQLException {
// 1. 得到 连接 (druid)
Connection connection = JDBCUtilsByDruid.getConnection();
// 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
// 3. 创建 QueryRunner
QueryRunner queryRunner = new QueryRunner();
// 4. 就可以执行相关的方法, 返回单个对象
String sql = "select * from actor where id = ?";
// 解读
// 因为我们返回的单行记录<--->单个对象, 使用的Hander 是 BeanHandler
Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 1);
System.out.println(actor);
// 释放资源
JDBCUtilsByDruid.close(null, null, connection);
}
// apache-dbutils + druid 完成查询结果是单行单列-返回的就是object
@Test
public void testScalar() throws SQLException {
// 1. 得到 连接 (druid)
Connection connection = JDBCUtilsByDruid.getConnection();
// 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
// 3. 创建 QueryRunner
QueryRunner queryRunner = new QueryRunner();
// 4. 就可以执行相关的方法,返回单行单列 , 返回的就是Object
String sql = "select name from actor where id = ?";
// 解读: 因为返回的是一个对象, 使用的handler 就是 ScalarHandler
Object obj = queryRunner.query(connection, sql, new ScalarHandler(), 2);
System.out.println(obj);
// 释放资源
JDBCUtilsByDruid.close(null, null, connection);
}
// apache-dbutils + druid 完成 dml (update, insert ,delete)
@Test
public void testDML() throws SQLException {
// 1. 得到 连接 (druid)
Connection connection = JDBCUtilsByDruid.getConnection();
// 2. 使用 DBUtils 类和接口, 先引入DBUtils 相关的jar, 加入到本Project
// 3. 创建 QueryRunner
QueryRunner queryRunner = new QueryRunner();
// 4. 这里组织sql 完成 update, insert delete
// String sql = "update actor set name = ? where id = ?";
// String sql = "insert into actor values(null, ?, ?, ?, ?)";
String sql = "delete from actor where id = ?";
// 解读
// (1) 执行dml 操作是 queryRunner.update()
// (2) 返回的值是受影响的行数 (affected: 受影响)
// int affectedRow = queryRunner.update(connection, sql, "林青霞", "女", "1966-10-10", "116");
int affectedRow = queryRunner.update(connection, sql, 1);
System.out.println(affectedRow > 0 ? "执行成功" : "执行没有影响到表");
// 释放资源
JDBCUtilsByDruid.close(null, null, connection);
}
}