目录
问题引入
ResultSet
结果集只能在有连接的情况下使用一次
将 ResultSet
结果集封装到 ArrayList<Actor>
中
手写解决 ResultSet 的封装
-- actor 数据表
CREATE TABLE actor(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(32) NOT NULL DEFAULT '',
sex CHAR(1) NOT NULL DEFAULT '女',
borndate DATETIME,
phone VARCHAR(12)
);
-- 测试数据
INSERT INTO actor VALUES
(NULL, 'Gin', '男', '1975-12-12', '356'),
(NULL, 'Vodka', '男', '1977-6-7', '4869');
Actor 类
package Test;
import java.util.Date;
/**
* @Author: Gin
* @Description:
* @Modified By: Gin
* @Date: Created in 9:07 2021/9/15
*/
public class Actor {
private Integer id;
private String name;
private String sex;
private Date borndate;
private String phone;
// 无参构造器【一定要有无参构造器,反射需要】
// 全参数构造器
// get/set 方法
// HashCode & equals
// toString 方法
将 ResultSet 结果集封装到 ArrayList 中
package Test;
import org.junit.Test;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.Date;
/**
* @Author: Gin
* @Description:
* @Modified By: Gin
* @Date: Created in 9:02 2021/9/15
*/
public class Test19 {
@Test
public void testResultSetToArrayList() {
Connection connection = null;
String sql = "select * from actor where id >= 1";
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
ArrayList<Actor> list = new ArrayList<Actor>();
try {
connection = JDBCUtilsByDruid.getConnection();
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 1);
resultSet = preparedStatement.executeQuery();
while (resultSet.next()) {
Integer id = resultSet.getInt(1);
String name = resultSet.getString(2);
String sex = resultSet.getString(3);
Date borndate = resultSet.getDate(4);
String phone = resultSet.getString(5);
list.add(new Actor(id, name, sex, borndate, phone));
}
System.out.println("ArrayList 中的数据:" + list);
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtilsByDruid.close(resultSet, preparedStatement, connection);
}
}
}
使用 Apache-DBUtils 进行 ResultSet 的封装
基本介绍
commons-dbutils
是 Apache 组织提供的一个开源 JDBC 工具类库,它是对 JDBC 的封装,使用 dbutils 能极大简化 JDBC 编码的工作量。
DBUtils类
QueryRunner
类:该类封装了 SQL 的执行,是线程安全的。可以实现增、删、改、查、批处理- 使用
QueryRunner
类实现查询 ResultSetHandler
接口:该接口用于处理java.sqI.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
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
<version>1.6</version>
</dependency>
查询实现【查询结果集、单行结果、单行单列结果】
package Test;
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.Test;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
/**
* @Author: Gin
* @Description:
* @Modified By: Gin
* @Date: Created in 9:25 2021/9/15
*/
public class Test20 {
/**
* 演示:查询结果集
* @throws SQLException
*/
@Test
public void testApacheDBUtils() throws SQLException {
Connection connection = JDBCUtilsByDruid.getConnection();
// 使用 Apache-DBUtils 类和接口,先导入 Apache-DBUtils 的 jar 包
// 创建 QueryRunner 对象
QueryRunner queryRunner = new QueryRunner();
// SQL 语句
String sql = "select * from actor where id >= ?";
// 执行相关方法,返回 ArrayList 集合
// 1. 以下 query 方法就是执行 SQL 语句,得到 ResultSet 结果集 --- 封装到 --- ArrayList 集合中
// 2. 返回集合
// 3. connection:连接
// 4. sql:要执行的 SQL 语句
// 5. new BeanListHandler<>(Actor.class):将 ResultSet 通过 Actor 对象封装到 ArrayList 集合中
// 底层使用反射机制去获取 Actor 的属性,然后进行封装
// 6. ...params:1 给 SQL语句 中的 ? 赋值
// 7. 底层得到的 ResultSet 会在 query 关闭,关闭 PreparedStatement
/**
* query 方法 的底层源码:
* private <T> T query(Connection conn, boolean closeConn, String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException {
* if (conn == null) {
* // 判断连接是否为空,为空则抛异常
* throw new SQLException("Null connection");
* } else if (sql == null) {
* if (closeConn) {
* this.close(conn);
* }
* // 判断 Statement 是否为空,为空则抛异常
* throw new SQLException("Null SQL statement");
* } else if (rsh == null) {
* if (closeConn) {
* this.close(conn);
* }
* // 判断 ResultSetHandler 是否为空,为空则抛异常
* throw new SQLException("Null ResultSetHandler");
* } else {
* 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【使用反射】
* } catch (SQLException var33) {
* this.rethrow(var33, sql, params);
* } finally {
* try {
* this.close(rs); // 关闭 ResultSet
* } finally {
* this.close(stmt); // 关闭 PreparedStatement
* if (closeConn) {
* this.close(conn); // 关闭 conn 连接
* }
*
* }
* }
*
* 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);
}
/**
* 演示:返回的结果是单行记录(单个对象)
* @throws SQLException
*/
@Test
public void testQuerySingle() throws SQLException {
Connection connection = JDBCUtilsByDruid.getConnection();
// 创建 QueryRunner 对象
QueryRunner queryRunner = new QueryRunner();
// SQL语句
String sql = "select * from actor where id = ?";
// 返回单行记录,使用的 Handler 是 BeanHandler
Actor actor = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 2);
System.out.println(actor);
// 释放资源
JDBCUtilsByDruid.close(null, null, connection);
}
/**
* 演示:查询单行单列的数据
* @throws SQLException
*/
@Test
public void testQueryScalar() throws SQLException {
Connection connection = JDBCUtilsByDruid.getConnection();
// 创建 QueryRunner 对象
QueryRunner queryRunner = new QueryRunner();
// SQL语句
String sql = "select name from actor where id = ?";
// 返回的是 单行单列 的数据,使用 ScalarHandler
Object query = queryRunner.query(connection, sql, new ScalarHandler(), 2);
System.out.println(query);
// 释放资源
JDBCUtilsByDruid.close(null, null, connection);
}
}
DML 实现【增、删、改】
/**
* 演示:执行 DML 语句(增、删、改)
*/
@Test
public void testDML() throws SQLException {
Connection connection = JDBCUtilsByDruid.getConnection();
// 创建 QueryRunner 对象
QueryRunner queryRunner = new QueryRunner();
// SQL语句
// 1. 修改
// String sql = "update actor set name = ? where id = ?";
// 2. 增加
// String sql = "insert into actor values (null, ?, ?, ?, ?)";
// 3. 删除
String sql = "delete from actor where id = ?";
// update 方法的返回值表示:受影响的行数
// 1. 修改
// int rows = queryRunner.update(connection, sql, "Vermouth", 2);
// 2. 增加
// int rows = queryRunner.update(connection, sql, "Rum", "男", "1958-2-9", "356");
// 3. 删除
int rows = queryRunner.update(connection, sql, 4);
// 显示修改操作是否成功
System.out.println(rows > 0 ? "修改成功" : "修改无效");
// 释放资源
JDBCUtilsByDruid.close(null, null, connection);
}