JDBC——Apache-DBUtils

问题引入

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类

  1. QueryRunner 类:该类封装了 SQL 的执行,是线程安全的。可以实现增、删、改、查、批处理
  2. 使用 QueryRunner 类实现查询
  3. ResultSetHandler 接口:该接口用于处理 java.sqI.ResultSet ,将数据按要求转换为另一种形式

方法

  1. ArrayHandler:把结果集中的第一行数据转成对象数组。
  2. ArrayListHandler:把结果集中的每一行数据都转成一个数组,再存放到 List中。
  3. BeanHandler:将结果集中的第一行数据封装到一个对应的 JavaBean 实例中。
  4. BeanListHandler:将结果集中的每一行数据都封装到一个对应的 JavaBean 实例中,存放到List里。
  5. ColumnListHandler:将结果集中某一列的数据存放到 List 中。
  6. KeyedHandler(name):将结果集中的每行数据都封装到 Map 里,再把这些map再存到一个 map 里,其 key 为指定的 key.
  7. MapHandler:将结果集中的第一行数据封装到一个 Map 里,key 是列名,value 就是对应的值。
  8. 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);

    }
    

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值