首页 > 其他分享 >DBUtils的使用

DBUtils的使用

时间:2023-02-01 09:46:13浏览次数:49  
标签:queryRunner Admin 使用 admin connection sql query DBUtils

一. DBUtils的引出

1、connection不能提前关闭

当我们查出结果集resultSet的时候,就关闭了connection连接,这时resultSet就不能使用了

示例代码如下:

public class jdbcDBUtils {
    @Test
    public void test() throws Exception{
        Connection connection = JDBCUtils.getConnection();
        String sql = "select * from admin";
        PreparedStatement preStatement = connection.prepareStatement(sql);
        ResultSet resultSet = preStatement.executeQuery();

        /**注意:
         * 以下三种方式,都会导致 java.sql.SQLException: Operation not allowed after ResultSet closed
         * 在使用完resultSet结果集之前,不能将resultSet、preStatement、connection关闭。
         */
        //JDBCUtils.Close(resultSet,null,null);
        //JDBCUtils.Close(null,preStatement,null);
        JDBCUtils.Close(null,null,connection);

        while(resultSet.next()){
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String pwd = resultSet.getString("pwd");
            System.out.println("id:" + id +" name:" + name + " pwd:" + pwd);
        }
    }
}

运行结果如下:

vip

总结:在使用resultSet结果集之前,不能提前关闭resultSet,preStatement以及connection。

2.resultSet无法重复使用

当遍历完resultSet之后,肯定要关闭连接,导致resultSet无法重复使用。

由1和2引出如下问题:

  ① 如何让resultSet结果集重复使用

  ② 在遍历的过程中,能否简化遍历过程

解决方案:使用DBUtils的jar包

二. DBUtils的使用

1. 在libs中引入dbutils的jar包

2. query语句:

  ① 将表中数据全部查找出来【多行】

public class jdbcDBUtils {
    /**
     * 查询表中所有结果
     * @throws Exception
     */
    @Test
    public void testSearchAll() throws Exception{
        // 1. 在libs中引入dbutils的jar包
        // 2. 获取druid连接池的连接
        Connection connection = JDBCUtilsByDruid.getConnection();
        // 3.使用queryRunner查询结果
        String sql = "select * from admin";
        QueryRunner queryRunner = new QueryRunner();
        // 4.将connection,sql,bean对象,作为参数放入query()中
        //      1)传入连接connection
        //      2)传入sql语句
        //      3)传入bean对象 new BeanListHandler<>(Admin.class) 【反射机制】
        //        resultSet -> admin对象 -> List<Admin>集合
        /** QueryRunner的query()源码如下:
         * 1) public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh) throws SQLException {
         *         return this.query(conn, sql, rsh, (Object[])null);
         *
         * }
         * 注意在 1) 中 调用 2) 时,传入的可变参数是null
         *
         * 2) public <T> T query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
         * throws SQLException {
         *         PreparedStatement stmt = null;
         *         ResultSet rs = null;
         *         Object result = null;
         *
         *         try {
         *             // 通过conn和sql创建PreparedStatement类的stmt对象
         *             stmt = this.prepareStatement(conn, sql);
         *             // 将可变参数params传入给sql语句的占位符?
         *             this.fillStatement(stmt, params);
         *             // stmt执行sql语句
         *             rs = this.wrap(stmt.executeQuery());
         *             // 将得到的结果集resultSet--反射机制-->admin对象--封装-->result集合中
         *             result = rsh.handle(rs); // handle()动态绑定机制
         *         } catch (SQLException var33) {
         *             this.rethrow(var33, sql, params);
         *         } finally {
         *             try {
         *                 this.close(rs);
         *             } finally {
         *                 this.close((Statement)stmt);
         *             }
         *         }
         *
         *         // 返回result集合
         *         return result;
         *     }
         */
        List<Admin> query = queryRunner.query(connection,sql, new BeanListHandler<>(Admin.class));
        for (Admin admin : query) {
            System.out.println(admin);
        }
        JDBCUtilsByDruid.Close(null,null,connection);
    }
}

  ①运行结果如下:

Admin{id=3, name='Tom3', pwd='123'}
Admin{id=5, name='Tom2', pwd='123'}
Admin{id=6, name='Tom3', pwd='123'}
Admin{id=8, name='Tom2', pwd='123'}
Admin{id=9, name='Tom3', pwd='123'}
Admin{id=11, name='zw', pwd='123'}
Admin{id=12, name='郑为', pwd='1234'}
Admin{id=13, name='郑威', pwd='1234'}
Admin{id=14, name='郑为', pwd='1234'}
Admin{id=15, name='郑威', pwd='1234'}

Process finished with exit code 0
View Code

  注意①中源码 1) 和 2) 的区别,体现了重载的好处。

  ② 将表中数据按照指定条件筛选出来【单行】

public class jdbcDBUtils {
    /**
     * 查询单行结果
     * @throws Exception
     */
    @Test
    public void testSearchSingle() throws Exception{
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select * from admin where id = ?";
        Admin admin = queryRunner.query(connection, sql, new BeanHandler<>(Admin.class),3);
        System.out.println(admin);
        JDBCUtilsByDruid.Close(null,null,connection);
    }
}

  ② 运行结果如下:

Admin{id=3, name='Tom3', pwd='123'}

  ③ 将表中的某一字段按照指定条件筛选出来【单行单列】

public class jdbcDBUtils {
    /**
     * 执行单行单列的查询
     * @throws Exception
     */
    @Test
    public void testSearchScalar() throws Exception{
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        String sql = "select name from admin where id = ?";
        Object query = queryRunner.query(connection, sql, new ScalarHandler(), 3);
        System.out.println(query);
        JDBCUtilsByDruid.Close(null,null,connection);
    }
}

  ③ 运行结果如下:

Tom3

①,②,③的区别

① 返回集合,调用的方法:

List<Admin> query = queryRunner.query(connection,sql, new BeanListHandler<>(Admin.class));

  具体运行步骤:resultSet--反射机制--》admin对象--封装--》result集合中。

② 返回对象,调用的方法:

Admin admin = queryRunner.query(connection, sql, new BeanHandler<>(Admin.class),3);

  具体运行步骤:resultSet--反射机制--》admin对象。

③ 返回字段,调用的方法:

Object query = queryRunner.query(connection, sql, new ScalarHandler(), 3);

总结1:

vip

ScalarHandler、BeanHandler、BeanListHandler 都实现了 handle()的方法,①的源码 result = rsh.handle(rs),由动态绑定机制可知,result结果不相同

总结2:

   当需要查出多行数据集时,使用 new BeanListHandler<>(Admin.class) ;

   当需要查出单行数据时,使用 new BeanHandler<>(Admin.class);

   当需要查出单行单例【字段】时,使用 new ScalarHandler()。

3. update语句

public class jdbcDBUtils {
    /**
     * 执行DML语句
     * @throws Exception
     */
    @Test
    public void testDML() throws Exception{
        Connection connection = JDBCUtilsByDruid.getConnection();
        QueryRunner queryRunner = new QueryRunner();
        // 增加insert
        /*
        String insert = "insert into admin values(null,?,?),(null,?,?)";
        int ins = queryRunner.update(connection, insert, "郑为", "1234", "郑威", "1234");
        System.out.println(ins > 0 ? "添加成功":"添加失败");
         */

        // 修改update
        /*
        String update = "update admin set pwd = ? where id = ?";
        int upd = queryRunner.update(connection, update, "123456", 2);
        System.out.println(upd > 0 ? "更新成功":"更新失败");
         */

        // 删除delete
        /*
        String delete = "delete from admin where id = ?";
        queryRunner.update(connection,delete,2);
         */

        // 展现查询结果集,验证是否插入成功
        String sql = "select * from admin";
        // new BeanListHandler<>(Admin.class) 反射机制 result->admin对象->装入list集合
        List<Admin> query1 = queryRunner.query(connection, sql, new BeanListHandler<>(Admin.class));
        for (Admin admin : query1) {
            System.out.println(admin);
        }

        // 查询单行结果,验证是否修改/删除成功
        sql = "select * from admin where id = ?";
        Admin query2 = queryRunner.query(connection, sql, new BeanHandler<>(Admin.class),2);
        System.out.println(query2);

        // 带条件的查询,查询结果
        sql = "select * from admin where name = ?";
        List<Admin> query3 = queryRunner.query(connection, sql, new BeanListHandler<>(Admin.class), "郑为");
        for (Admin admin : query3) {
            System.out.println(admin);
        }
        JDBCUtilsByDruid.Close(null,null,connection);
    }
}

4. 总结

a:使用DBUtils工具类时,无论执行查询语句,还是DML语句,都是由QueryRunner类的对象queryRunner来执行;

b:查询时,queryRunner调用query()方法;修改【增,删,改】时,queryRunner调用update()方法;

c:执行sql语句时,queryRunner(连接名,SQL语句,具体语句具体分析)。

  如果是查询,则是2中①②③的某一类的对象;

  如果是修改,则是3中传入参数。

 

标签:queryRunner,Admin,使用,admin,connection,sql,query,DBUtils
From: https://www.cnblogs.com/zwgitOne123/p/17081518.html

相关文章

  • vue3 自定义组件中使用 v-model
    1、直接绑定v-model,但是Props要固定为modelValue组件D:注意这里的Props和Emits,必须使用Vue提供的defineProps()和defineEmits()。如果父组件想要使用v-mod......
  • 基于Docker安装的Stable Diffusion使用CPU进行AI绘画
    基于Docker安装的StableDiffusion使用CPU进行AI绘画由于博主的电脑是为了敲代码考虑买的,所以专门买的高U低显,i9配核显,用StableDiffusion进行AI绘画的话倒是专门有个......
  • 使用FreeSQL走过的坑
    FreeSQL还挺好用的,后续的新项目,用到数据库的,基本上都改用FreeSQL了。但是在FreeSQL的过程中,不可避免地踩过一些坑,分享出来供大家参考。1、慎用UseAutoSyncStructu......
  • RabbitMq使用中常见错误--python版
    用python的pika库错误集 一、pika.exceptions.ProbableAuthenticationError:ConnectionClosedByBroker:(403)‘ACCESS_REFUSED-Loginwasrefusedusingauthentica......
  • react-vant 使用
    react-vant是vantUI针对react的UI版本,可以帮助我们搭建react移动端页面安装:npminstallreact-vantlist组件使用import{List}from'react-vant';例子/*eslint-d......
  • 第六十二章 使用 SNMP 监控 IRIS
    第六十二章使用SNMP监控IRIS本附录描述了IRIS数据平台和SNMP(简单网络管理协议)之间的接口。SNMP是一种通信协议,作为一种管理TCP/IP网络(包括单个网络设备和一般......
  • .NET7 中使用MailKit
    MailKit正式替换了.NET的SmtpClient可参考:SmtpClient类(System.Net.Mail)|MicrosoftLearnstaticvoidSendMail(stringsubject,stringhtml)......
  • Go使用post方法将json数据传给一个url(后端接口)
       最近做的一个项目是采用前后端分离模式写前端,后端是fabric区块链,提供接口,需要使用post方法进行访问。如上一章注册用户,就是需要把用户名、账户信息转换成json形式......
  • await使用不当引发的异常
    1、异步方法不await引发异常向文件写入大量内容:因为WriteAllTextAsync是独占式写入,又不等待,都没写完就到下一行读,肯定占用进程报错!2、await等待了一个非异步的方法......
  • nginx 重写整个 url,结合使用 proxy_pass 和 rewrite
    首先讲下需求背景需要将相同url不同参数的地址转发到服务器上不同的地址举例:example1.com/api.php?act=order->example2.com/api/pay/orderexample1.com/api.php?ac......