文章目录
Apache——DBUtils
分析问题
- 关闭connection后,resultSet 结果集无法使用
- resultSet 不利于数据的管理
自我总结
-
普通的JDBC得到connection连接,得到resultset结果集后,只能把resultset结果集完全读取完毕后才能关闭connection,非常的不方便
-
resultset结果集读取数据只能是“getInt,getString”,而不是比较直观的,getName,getId;
我们为一个表做成一个class,将结果集记录,封装到ArrayList<此类>中,按属性读取
用旧方法解决问题
新建Actor类,当做resultSet结果集内容
package com.taotao.jdbc.datasource;
import java.util.Date;
/**
* Create By 刘鸿涛
* 2022/3/5 16:00
* Actor 对象和 actor 表的记录对应
*/
public class Actor {
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) {
Id = id;
this.name = name;
this.sex = sex;
this.borndate = borndate;
this.phone = phone;
}
public Integer getId() {
return Id;
}
public void setId(Integer id) {
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 + '\'' +
'}';
}
}
测试读取
可以返回集合
@Test
public void testSelectToArraylist(){
//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();
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 2); //给?号赋值
//执行,得到结果集
set = preparedStatement.executeQuery();
//遍历该结果集
while (set.next()) {
int id = set.getInt("Id");
String name = set.getString("name");
String sex = set.getString("sex");
Date borndate = set.getDate("borndate");
String phone = set.getString("phone");
// System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
//把得到的result 的记录,封装到 Actor对象,放入到list集合
list.add(new Actor(id,name,sex,borndate,phone));
}
System.out.println("list集合数据=" + list);
} catch (SQLException e) {
e.printStackTrace();
} finally {
JDBCUtilsByDruid.close(set,preparedStatement,connection);
}
}
//因为ArrayList 和 connection 没有任何关联,所以该集合可以复用
方便之处在于
for (Actor actor :list){
System.out.println(actor.getSex,actor,getId);
}
Apache-DBUtils基本介绍
- commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的封装,使用dbutils能极大简化jdbc编码的工作量
DBUtils类
-
QueryRunner类:该类封装了SQL的执行,是线程安全的,可以实现增、删、改、查、批处理
-
使用QueryRunner类实现查询
-
ResultHandler接口:该接口用于处理 java.sql.ResultSet,将数据按要求转换为另一种形式
- ArrayHandler:把结果集中的第一行数据转成对象数组
- ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到List中
- BeanHandler:将结果集中的第一行数据封装到一个对应的JavaBean实例中
- BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里
- ColumnListHandler:将结果集中的某一列的数据存放到List中
- KeyedHandler(name):将结果集中的每行数据都封装到Map里,再把这些map再存到一个map里,其key为指定的key
- MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值
- MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
应用案例
使用DBUtils + 数据连接池(德鲁伊)方式,完成对表actor的crud
相关代码
Actor类
package com.taotao.jdbc.datasource;
import java.time.LocalDateTime;
/**
* Create By 刘鸿涛
* 2022/3/5 16:00
* Actor 对象和 actor 表的记录对应
*/
@SuppressWarnings({"all"})
public class Actor {
private Integer Id;
private String name;
private String sex;
private LocalDateTime borndate;
private String phone;
public Actor() { //一定要给一个无参构造器【反射需要】
}
public Actor(Integer id, String name, String sex, LocalDateTime borndate, String phone) {
Id = id;
this.name = name;
this.sex = sex;
this.borndate = borndate;
this.phone = phone;
}
public Integer getId() {
return Id;
}
public void setId(Integer id) {
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 LocalDateTime getBorndate() {
return borndate;
}
public void setBorndate(LocalDateTime 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 + '\'' +
'}';
}
}
DBUtils_USE.java
package com.taotao.jdbc.datasource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import org.junit.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
* Create By 刘鸿涛
* 2022/3/5 19:09
*/
@SuppressWarnings({"all"})
public class DBUtils_USE {
@Test
//使用DBUtils + 数据连接池(德鲁伊)方式,完成对表actor的crud
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 = ?";
//(1)query 方法就是执行sql语句,得到resultset --- 封装到 --> ArrayList 集合中
//(2)返回集合
//(3)connection:连接
//(4)sql:执行的sql语句
//(5)new BeanListHandler<>(Actor.class):在将resultset -> Actor 对象 -> 封装到 ArrayList
// 底层使用反射机制 去获取Acotr 类的属性,然后进行封装
//(6)1 就是给 sql语句中的?赋值,可以有多个值,因为是可变参数Object... params
//(7)底层得到的resultset,会在query 关闭,关闭PreparedStatment
List<Actor> list = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
System.out.println("输出集合的信息");
for (Actor actor:list){
System.out.println(actor);
}
//释放资源
JDBCUtilsByDruid.close(null,null,connection);
}
}
注意
这里的Date数据类型不再被解析,具体原因不明,可以选择LocalDateTime
DBUtils查询案例
查询一条记录
@SuppressWarnings({"all"})
@Test
//演示 apache-dbutils + druid 完成 返回的结果是单行记录(单个对象)
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(), 1);
System.out.println(obj);
//释放资源
JDBCUtilsByDruid.close(null,null,connection);
}
增删改(DML)案例
update
@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 = ?";
//(1)执行 dml 操作是queryRunner.update();
//(2)返回的值是受影响的行数(affected:受影响)
int affectedRow = queryRunner.update(connection, sql, "张三丰", 2);
System.out.println(affectedRow > 0 ? "执行成功":"执行没有影响到表");
//释放资源
JDBCUtilsByDruid.close(null,null,connection);
}
insert
@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 = "insert into actor values(3,?,?,?,?)";
//(1)执行 dml 操作是queryRunner.update();
//(2)返回的值是受影响的行数(affected:受影响)
int affectedRow = queryRunner.update(connection, sql, "周星驰","男","1998-10-12","1212");
System.out.println(affectedRow > 0 ? "执行成功":"执行没有影响到表");
//释放资源
JDBCUtilsByDruid.close(null,null,connection);
}
原因是我的Id字段没有设置auto_increment后缀,所以不能传入null,所以采用了固定值
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 = "delete from actor where Id = ?";
//(1)执行 dml 操作是queryRunner.update();
//(2)返回的值是受影响的行数(affected:受影响)
int affectedRow = queryRunner.update(connection, sql, 3);
System.out.println(affectedRow > 0 ? "执行成功":"执行没有影响到表");
//释放资源
JDBCUtilsByDruid.close(null,null,connection);
}