Java学习日志(三十四): DbUtils工具包的使用,四种常用Handler结果集

JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇)

DbUtils工具包

DbUtisl介绍

作用:使用apache commons组件DbUtils对数据库表进行增删改查(简化原生JDBC6步)

  • org.apache.commons.dbutils.QueryRunner类:用于执行sql语句
  • org.apache.commons.dbutils.DbUtils类:用于释放资源
  • org.apache.commons.dbutils.ResultSetHandler接口:用于接收查询的结果集

QueryRunner类使用
构造方法

  • QueryRunner():空参构造,调用update/query方法执行sql语句时,必须传递Connection对象
  • QueryRunner(DataSource ds)带连接池的构造方法,调用update/query方法执行sql语句时,无需传递Connection对象

注意:QueryRunner执行sql语句时,会自动在连接池获取连接使用,使用完毕,会自动把连接归还给连接池

成员方法

  • 用于执行增删改的update方法
  1. int update(Connection conn,String sql,Object... params) 空参构造使用

  2. int update(String sql,Object... params) 带连接池的构造方法使用

     参数:
        Connection conn:数据库连接对象,可以使用C3P0连接池获取。
        String sql:sql语句,可以使用?占位符。
        Object... params:?占位符的实际参数。
     返回值:
        int:影响数据库的有效行数。
    
  • 用于执行查询的Query方法:
  1. T query(Connection conn,String sql,ResultSetHandler<T> rsh,Object... params) 空参构造使用

  2. T query(String sql,ResultSetHandler<T> rsh,Object... params) 带连接池的构造方法使用

     参数:
        Connection conn:数据库连接对象,可以使用C3P0连接池获取。
        String sql:sql语句,可以使用?占位符。
        ResultSetHandler<T> rsh:用来接收查询结果的结果集,可以传递ResultSetHandler接口的实现类。
        Object... params:?占位符的实际参数。
     返回值:
        T:传递ResultSetHandler接口的实现类不同,QueryRunner处理查询结果的方式也不同,会返回不同的结果,
           传递哪种结果集,就返回对应的处理结果。
    

使用DbUtisl工具包对数据库进行增删改

使用的数据库表:
在这里插入图片描述

使用步骤:

  1. 创建QueryRunner对象
  2. 调用QueryRunner对象中的方法update/query执行sql语句,接收结果
  3. 处理结果

代码示例:不带连接池的QueryRunner(),使用增加数据(删改与之相同)

@Test
    public void testInsert() throws SQLException {
        //1.创建QueryRunner对象
        QueryRunner qr = new QueryRunner();
        //2.调用QueryRunner对象中的方法update/query执行sql语句,接收结果
        //int update(Connection conn,String sql,Object... params) 空参构造使用
        Connection conn = C3P0UtilsXML.getConnection();
        String sql = "INSERT INTO product(pid,pname,price,category_id) VALUES(?,?,?,?);";
        int row = qr.update(conn, sql, 14, "优乐美奶茶", 3, "c005");
        //3.处理结果
        System.out.println(row+"行数据添加成功!");
        //把连接归还给连接池
        DbUtils.closeQuietly(conn);
    }

重点带连接池的QueryRunner(DataSource ds),使用修改进行示例

@Test
    public void testUpdate() throws SQLException {
        //1.创建QueryRunner对象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.调用QueryRunner对象中的方法update/query执行sql语句,接收结果
        String sql = "UPDATE product SET price = ? WHERE pid = ?;";
        int row = qr.update(sql, 10, 14);
        //3.处理结果
        System.out.println(row+"行数据添加成功!");
    }

使用DbUtisl工具包对数据库进行查询

结果集使用BeanHandler

实现类BeanHandler
使用方式:
把查询的多行结果的第一行取出来,存储到一个javabean对象中返回

构造方法
BeanHandler(Class<T> type):传递javabean的class文件对象,传递Product.class
构造方法的内部原理

  1. 使用反射技术,根据传递的class文件对象,创建javabean对象
    Object obj = clazz.newInstance();
  2. 使用反射技术,为对象的每个成员赋值
    Method setNameMethod = clazz.getMethod("setXXX",String.class);
    Object v2 = setNameMethod.invoke(obj,"xxx");

T query(String sql,ResultSetHandler<T> rsh,Object... params) 带连接池的构造方法使用

返回值
T:传递哪个javabean的class文件对象,就返回哪个javabean对象(含有第一行值),传递Product.class就返回Product对象

使用前提
类中必须有空参构造方法

代码示例:Product类的javabean

import java.io.Serializable;

/*
    创建数据库product的javabean类
    数据库表与java中类的对应关系
        有product表-->Product类
        表中的列-->类中的成员变量
        表中的行-->Product对象-->多个对象存储到集合中
 */
public class Product implements Serializable {
    //商品主键
    private int pid;
    //商品名称
    private String pname;
    //商品价格
    private double price;
    //商品分类
    private String category_id;

    public Product() {
    }

    @Override
    public String toString() {
        return "Product{" +
                "pid=" + pid +
                ", pname='" + pname + '\'' +
                ", price=" + price +
                ", category_id='" + category_id + '\'' +
                '}';
    }

    public int getPid() {
        return pid;
    }

    public void setPid(int pid) {
        this.pid = pid;
    }

    public String getPname() {
        return pname;
    }

    public void setPname(String pname) {
        this.pname = pname;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public String getCategory_id() {
        return category_id;
    }

    public void setCategory_id(String category_id) {
        this.category_id = category_id;
    }
}

测试

@Test
    public void testBeanHandler() throws SQLException {
        //1.创建QueryRunner对象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.使用QueryRunner对象中的方法query,执行sql语句,获取结果
        String sql = "select * from product;";
        Product p = qr.query(sql, new BeanHandler<>(Product.class));
        //3.处理结果
        System.out.println(p);
    }

结果:把查询的多行结果的第一行取出来,只取出第一行
在这里插入图片描述

结果集使用BeanListHandler

实现类BeanListHandler
使用方式:把查询的多行结果,存储到多个javabean对象中,多个javabean对象存储到list集合中。

构造方法:
BeanListHandler(Class<T> type):传递javabean的class文件对象,传递Product.class
内部实现:也是使用反射技术

T query(String sql,ResultSetHandler<T> rsh,Object... params) 带连接池的构造方法使用
返回值:
T:传递哪个javabean的class文件对象,就存储javabean对象的List集合,传递Product.class就返回List

使用前提:
类中必须有空参构造方法

代码示例:测试

@Test
    public void testBeanListHandler() throws SQLException {
        //1.创建QueryRunner对象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.使用QueryRunner对象中的方法query,执行sql语句,获取结果
        String sql = "select * from product;";
        List<Product> listP = qr.query(sql, new BeanListHandler<>(Product.class));
        //3.处理结果
        for (Product p : listP) {
            System.out.println(p);
        }
    }

结果:查询多行数据
在这里插入图片描述

结果集使用ScalarHandler

实现类ScalarHandler
使用方式:用于接收sql语句是单一返回值的情况

  • 聚合函数:sum,avg,count,max,min
  • 获取某一行的某一个字段的值:select pname from product where pid = ?;

T query(String sql,ResultSetHandler<T> rsh,Object... params) 带连接池的构造方法使用
返回值
T:返回值类型多种类型,所以使用Object类型来接收这个值。

代码示例:

@Test
    public void testScalarHandler() throws SQLException {
        //1.创建QueryRunner对象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        //2.调用QueryRunner对象中的方法query执行sql语句,获取结果
        //String sql = "select count(*) from product;";
        String sql = "select pname from product where pid = ?;";
        Object obj = qr.query(sql, new ScalarHandler(),10);
        //3.处理结果集
        //System.out.println(obj);//14
        System.out.println(obj);//面霸
    }

结果集使用ColumnListHandler

实现类ColumnListHandler
使用方式:用于查询指定的,把指定列的数据存储到一个list集合中返回

构造方法

  • ColumnListHandler() 没有指定列,默认查询第1列
  • ColumnListHandler(int columnIndex) 指定列的索引,从第1列开始
  • ColumnListHandler(String columnName) 指定列名

T query(String sql,ResultSetHandler<T> rsh,Object... params) 带连接池的构造方法使用
返回值:
T返回存储列中数据的List集合,因为列的数据类型有多种,集合的泛型使用Object, List < Object>

注意查询的结果必须包含指定的列,否则会报SQLException异常:Column 'xxx' not found。

代码示例:ColumnListHandler() 没有指定列,默认查询第1列

@Test
    public void testColumnListHandler() throws SQLException {
        //1.创建QueryRunner对象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        2.调用QueryRunner对象中的方法query执行sql语句,获取结果
        String sql = "select * from product";
        List<Object> list = qr.query(sql, new ColumnListHandler());//没有指定列,默认查询第1列
        //3.处理结果集
        for (Object obj : list) {
            System.out.println(obj);
        }
    }

结果
在这里插入图片描述

ColumnListHandler(int columnIndex) 指定列的索引为第2列
ColumnListHandler(String columnName) 指定列名为pname

@Test
    public void testColumnListHandler() throws SQLException {
        //1.创建QueryRunner对象
        QueryRunner qr = new QueryRunner(C3P0UtilsXML.getDataSource());
        2.调用QueryRunner对象中的方法query执行sql语句,获取结果
        String sql = "select * from product";
        //List<Object> list = qr.query(sql, new ColumnListHandler());//没有指定列,默认查询第1列
        //List<Object> list = qr.query(sql, new ColumnListHandler(2));//列的索引为2,pname
        List<Object> list = qr.query(sql, new ColumnListHandler("pname"));//列的索引为2,pname
        //3.处理结果集
        for (Object obj : list) {
            System.out.println(obj);
        }
    }

结果
在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值