【JDBC】4.JDBCUtils实现CRUD操作

DBUtils实现CRUD操作

API介绍:

  • org.apache.commons.dbutils.QueryRunner

  • org.apache.commons.dbutils.ResultSetHandler

  • 工具类:org.apache.commons.dbutils.DbUtils

  • QueryRunner提供数据库操作的一系列重载的update()和query()操作

  • QueryRunner类提供了两个构造器:
    默认的构造器
    需要一个 javax.sql.DataSource 来作参数的构造器

  • ResultSetHandler接口用于处理数据库查询操作得到的结果集。不同的结果集的情形,由其不同的子类实现

1.添加

方式一:向数据表中添加一条记录

    @Test
    public void test1() {
        Connection connection = null;

        try {
            //1. 先获取数据库的连接 调用工具类
            connection = JDBCUtils.getConnection();
            //2. 提供一个添加操作的sql
            String sql = "insert into customers(name,email,birth)values('王海','tom@126.com','2020-09-08')";

            //3. 使用提供好的QueryRunner,调用update()方法,实现数据的插入
            QueryRunner runner = new QueryRunner();
            int count = runner.update(connection, sql);
            System.out.println("添加了" + count + "条记录");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4. 资源的关闭
            JDBCUtils.close(connection);
        }
    }

在这里插入图片描述
方式二:使用带占位符的sql 比较推荐 共用一个sql 大文件用 insert一次一条


    @Test
    public void test2() {
        Connection connection = null;

        try {
            //1. 先获取数据库的连接
            connection = JDBCUtils.getConnection();

            //2. 提供一个包含占位符的sql  '?'就是占位符
            //String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)";
            String sql = "insert into customers(name,email,birth)values(?,?,?)";

            //3. 使用提供好的QueryRunner,调用update()方法,实现数据的插入
            QueryRunner runner = new QueryRunner();
            //有几个占位符添加几个参数
            int count = runner.update(connection, sql,"丸子","wanzi@163.com","2021-10-5");
            //int count = runner.update(connection, sql,"丸子","wanzi@163.com",new Date(23423423432423L));
            System.out.println("添加了" + count + "条记录");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4. 资源的关闭
            JDBCUtils.close(connection);
        }
    }

在这里插入图片描述

2.删除(使用占位符)

//删除记录的操作  自带批量
    @Test
    public void test3(){
        Connection connection = null;

        try {
            //1. 先获取数据库的连接
            connection = JDBCUtils.getConnection();

            //2. 提供一个包含占位符的sql
            String sql = "delete from customers where id > ?";

            //3. 使用提供好的QueryRunner,调用update()方法,实现数据的插入
            QueryRunner runner = new QueryRunner();
            //params:19填充占位符
            int count = runner.update(connection, sql,19);
            System.out.println("删除了" + count + "条记录");

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4. 资源的关闭
            JDBCUtils.close(connection);
        }
    }

3.修改

 //修改表数据的操作 自带批量
    @Test
    public void test4(){
        Connection connection = null;

        try {
            //1. 先获取数据库的连接
            connection = JDBCUtils.getConnection();

            //2. 提供一个包含占位符的sql
            String sql = "update customers set email = ? where id = ?";

            //3. 使用提供好的QueryRunner,调用update()方法,实现数据的插入
            QueryRunner runner = new QueryRunner();
            //params填充占位符
            int count = runner.update(connection, sql,"tom@gmail.com",19);
            System.out.println("修改了" + count + "条记录");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4. 资源的关闭
            JDBCUtils.close(connection);
        }
    }

在这里插入图片描述

4.查询

ResultSetHandler接口的主要实现类:

  • BeanHandler:对应查询表中的一条记录,以对象的方式返回
  • BeanListHandler:对应查询表中的多条记录,以对象构成的集合的方式返回
  • MapHandler:对应查询表中的一条记录,结果集ResultSetHandler<Map<String,Object>>里的数据以map对象的方式返回。
    map中key为表中的字段名,map中value为表中一条数据的数据值。
  • MapListHandler:对应查询表中的多条记录,以map对象构成的List的方式返回。ResultSetHandler<List<Map<String, Object>>> 。按map中的key排序
    map中key为表中的字段名,map中value为表中一条数据的数据值。
  • ScalarHandler:用于查询表中的特殊值。比如:count(*) \ max(xxx)

query源码:

ResultSetHandler<T> rsh 表示结果集

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 {
            stmt = this.prepareStatement(conn, sql);
            this.fillStatement(stmt, params);
            rs = this.wrap(stmt.executeQuery());
            result = rsh.handle(rs);
        } catch (SQLException var33) {
            this.rethrow(var33, sql, params);
        } finally {
            try {
                this.close(rs);
            } finally {
                this.close((Statement)stmt);
            }
        }

        return result;
    }

BeanHandler源码:

public class BeanHandler<T> implements ResultSetHandler<T> {
    private final Class<T> type;
    private final RowProcessor convert;

    public BeanHandler(Class<T> type) {
        this(type, ArrayHandler.ROW_PROCESSOR);
    }

    public BeanHandler(Class<T> type, RowProcessor convert) {
        this.type = type;
        this.convert = convert;
    }

    public T handle(ResultSet rs) throws SQLException {
        return rs.next() ? this.convert.toBean(rs, this.type) : null;
    }
}

测试数据表的查询操作,返回结果集:

public class QueryTest {

    /*
    * BeanHandler:对应查询表中的一条记录,以对象的方式返回
    *
    * */
    @Test
    public void test1() {
        Connection connection = null;

        try {
            //1.获取数据库的连接
            connection = JDBCUtils.getConnection();

            //2.提供一条带占位符的查询语句sql
            String sql = "select id,name,email,birth from customers where id = ?";

            //3. 创建QueryRunner的实例
            QueryRunner runner = new QueryRunner();

            //4. 通过QueryRunner的实例,调用其query()  BeanHandler
            BeanHandler<Customer> handler = new BeanHandler<>(Customer.class);
            Customer customer = runner.query(connection, sql, handler, 1);
            System.out.println(customer);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5. 关闭资源
            JDBCUtils.close(connection);
        }


    }


    /*
     * BeanListHandler:对应查询表中的多条记录,以对象构成的集合的方式返回
     *
     * */
    @Test
    public void test2() {
        Connection connection = null;

        try {
            //1.获取数据库的连接
            connection = JDBCUtils.getConnection();

            //2.提供一条带占位符的查询语句sql
            String sql = "select id,name,email,birth from customers where id > ?";

            //3. 创建QueryRunner的实例
            QueryRunner runner = new QueryRunner();

            //4. 通过QueryRunner的实例,调用其query() BeanListHandler---- ResultSetHandler<List>
            //BeanListHandler<Customer> handler = new BeanListHandler<>(Customer.class);
            ResultSetHandler<List<Customer>> handler = new BeanListHandler<>(Customer.class);
            List<Customer> list = runner.query(connection, sql, handler, 1);

            list.forEach(System.out::println);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5. 关闭资源
            JDBCUtils.close(connection);
        }


    }

    /*
     * MapHandler:对应查询表中的一条记录,结果集ResultSetHandler<Map<String,Object>>里数据以map对象的方式返回。
     * map中key为表中的字段名,map中value为表中一条数据的数据值。
     *
     * */
    @Test
    public void test3() {
        Connection connection = null;

        try {
            //1.获取数据库的连接
            connection = JDBCUtils.getConnection();

            //2.提供一条带占位符的查询语句sql
            String sql = "select id,name,email,birth from customers where id = ?";

            //3. 创建QueryRunner的实例
            QueryRunner runner = new QueryRunner();

            //4. 通过QueryRunner的实例,调用其query()
            //MapHandler handler = new MapHandler();
            //结果集 Map<String,Object>
            ResultSetHandler<Map<String,Object>> handler = new MapHandler();
            Map<String, Object> map = runner.query(connection, sql, handler, 1);

            System.out.println(map);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5. 关闭资源
            JDBCUtils.close(connection);
        }

    }

    /*
     * MapListHandler:对应查询表中的多条记录,以map对象构成的List的方式返回。ResultSetHandler<List<Map<String, Object>>>
     *     按map中的key排序
     * map中key为表中的字段名,map中value为表中一条数据的数据值。
     *
     * */
    @Test
    public void test4() {
        Connection connection = null;

        try {
            //1.获取数据库的连接
            connection = JDBCUtils.getConnection();
            //2.提供一条带占位符的查询语句sql
            String sql = "select id,name,email,birth from customers where id > ?";
            //3. 创建QueryRunner的实例
            QueryRunner runner = new QueryRunner();
            //4. 通过QueryRunner的实例,调用其query()
            ResultSetHandler<List<Map<String, Object>>> handler = new MapListHandler();
            List<Map<String, Object>> list = runner.query(connection, sql, handler, 1);

            list.forEach(System.out::println);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5. 关闭资源
            JDBCUtils.close(connection);
        }
    }

    /*
    * ScalarHandler:用于查询表中的特殊值。比如:count(*) \ max(xxx)
    *
    * */
    @Test
    public void test5(){
        Connection connection = null;

        try {
            //1.获取数据库的连接
            connection = JDBCUtils.getConnection();
            //2.提供一条带占位符的查询语句sql
            String sql = "select count(*) from customers";
            //3. 创建QueryRunner的实例
            QueryRunner runner = new QueryRunner();
            //4. 通过QueryRunner的实例,调用其query()
            ScalarHandler handler = new ScalarHandler();
            long count = (long) runner.query(connection, sql, handler);

            System.out.println("查询到表中一共有" + count + "条记录");
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5. 关闭资源
            JDBCUtils.close(connection);
        }
    }

    @Test
    public void test6(){
        Connection connection = null;

        try {
            //1.获取数据库的连接
            connection = JDBCUtils.getConnection();
            //2.提供一条带占位符的查询语句sql
            String sql = "select max(birth) from customers";
            //3. 创建QueryRunner的实例
            QueryRunner runner = new QueryRunner();
            //4. 通过QueryRunner的实例,调用其query()
            ScalarHandler handler = new ScalarHandler();
            Date birth = (Date) runner.query(connection, sql, handler);

            System.out.println("查询到表中最大的birth是:" + birth);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //5. 关闭资源
            JDBCUtils.close(connection);
        }
    }
}
SELECT id,NAME,email,birth FROM customers WHERE id = 1;

sql查询结果集如下👇
在这里插入图片描述

对应test1运行,查询一条数据结果如下:
在这里插入图片描述
查询多条数据结果如下:
在这里插入图片描述
以map对象的方式返回:
在这里插入图片描述
以List<Map<String, Object>>的方式返回结果集如下:
在这里插入图片描述

test5运行结果如下:
在这里插入图片描述

ORM(object relational mapping)编程思想:

  • 数据库中的一个表 与 Java中的一个类对应
  • 表中的一条记录 与 类中一个对象对应
  • 表中的一个列(或字段) 与 类中的一个属性对应
public class Customer {
    private int id;
    private String name;
    private String email;
    private Date birth;
//    private Blob photo;


    @Override
    public String toString() {
        return "Customer{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", birth=" + birth +
                '}';
    }

    public Customer(int id, String name, String email, Date birth) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.birth = birth;
    }

    public Customer() {
    }

    public int getId() {

        return id;
    }

    public void setId(int id) {

        this.id = id;
    }

    public String getName() {

        return name;
    }

    public void setName(String name) {

        this.name = name;
    }

    public String getEmail() {

        return email;
    }

    public void setEmail(String email) {

        this.email = email;
    }

    public Date getBirth() {

        return birth;
    }

    public void setBirth(Date birth) {

        this.birth = birth;
    }
}
如果表中的字段名与类中的属性名不一致,为了查询操作结果的准确性,我们需要编写sql时,使用类的属性名作为select后字段的别名出现。

在这里插入图片描述
👇
在这里插入图片描述

SELECT order_id,order_name,order_date FROM `order` WHERE order_id = 1;

在这里插入图片描述

SELECT order_id orderId,order_name orderName,order_date orderDate FROM `order` WHERE order_id =1;

在这里插入图片描述

代码如下:

public class QueryTest {

    /*
    * 查询order表中的一条记录,返回Order类的一个对象
    *
    * */
    @Test
    public void test1() throws Exception {

        //3个参数
        Connection connection = JDBCUtils.getConnection();
        //SELECT order_id orderId,order_name orderName,order_date orderDate FROM `order` WHERE order_id = ? 起别名
        //使列名和java中的属性名一致
        String sql = "SELECT order_id orderId,order_name orderName,order_date orderDate FROM `order` WHERE order_id = ?";
        BeanHandler<Order> handler = new BeanHandler<>(Order.class);


        //核心代码
        QueryRunner runner = new QueryRunner();
        Order order = runner.query(connection, sql, handler, 1);

        System.out.println(order);

    }

}

在这里插入图片描述

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值