Javaweb学习笔记之DbUtils(一):增删改查

 

package com.jdbc.dbutils;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * 1、DbUtils 简介:
 *      DbUtils 是 java 编程中的数据库操作实用工具,小巧、简单、实用;
 *      DbUtils 封装了对 JDBC 的操作,简化了 JDBC 操作,可以少写代码;
 *
 *      对于数据库的读操作,DbUtils 可以把结果直接转换成 List、Array、Set 等 java 集合,便于程序员操作;
 *      对于数据库的写操作,也变的很简单,只需要写 sql 语句;
 *      可以使用 数据源、JNDI、数据库连接池 等技术来优化性能 -- 重用已经构建好的数据库连接对象;
 *
 * 2、DbUtils 的核心对象:
 *      QueryRunner 类:提供对 sql 语句操作的 API;
 *          query():用于执行 select 语句;
 *          update():用于执行 insert、update、delete 语句;
 *          batch():批处理;
 *      ResultSetHandler 接口:用于定义 select 操作后,怎样封装结果集;
 *      DbUtils 类:他就是一个工具类,定义了关闭资源与事务处理的方法;
 *
 * 3、DbUtils 导入的 jar 包:
 *      commons-dbutils-1.6.jar
 */
public class Demo1 {

    /**
     * DbUtils 执行 sql 语句 插入数据
     */
    @Test
    public void testInsert() throws Exception{
        // 创建 QueryRunner 对象,传入数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句插入数据
        int num = queryRunner.update("insert into users(username, password) values('lily', '321')");
        if (num > 0){
            System.out.println("插入数据成功,影响了" + num + "行.");
        }

        // 执行 sql 语句插入数据,传入参数
        // 接收参数的方法定义:update(String sql, Object... params)
        // 最后一个参数 Object... 表示是可变参数,是需要传入到参数 1 的 sql 语句中的值;
        num = queryRunner.update("insert into users(username, password) values(?, ?)", "lucy", "456");
        if (num > 0){
            System.out.println("插入数据成功,影响了" + num + "行.");
        }
    }

    /**
     * DbUtils 执行 sql 语句 修改数据
     */
    @Test
    public void testUpdate() throws Exception{
        // 创建 QueryRunner 对象,传入数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,修改数据
        int num = queryRunner.update("update users set username=?, password=? where id=?", "Jack", "789", 24);
        if (num > 0){
            System.out.println("修改数据成功,影响了" + num + "行.");
        }
    }

    /**
     * DbUtils 执行 sql 语句 删除数据
     */
    @Test
    public void testDelete() throws Exception{
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,删除数据
        int num = queryRunner.update("delete from users where id=?", 23);
        if (num > 0){
            System.out.println("删除数据成功,影响了" + num + "行.");
        }
    }

    /**
     * DbUtils 执行 批处理 语句
     * 批处理只能执行相同的 sql 语句
     */
    @Test
    public void testBatch() throws Exception{
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 定义一个 二位数组,作为 批处理语句的 参数
        String[][] param = new String[10][];    // 表示循环 10 次,执行 10 次 sql 语句
        for (int i = 0; i < param.length; i++) {
            param[i] = new String[]{"jerry" + i, "66" + i}; // 给每次执行的 sql 语句中的 ? 赋值
        }

        // 执行 批处理语句
        int[] num = queryRunner.batch("insert into users(username, password) values(?, ?)", param);
    }

    /**
     * DbUtils 执行 sql 语句查询数据
     * 使用 ResultSetHandler 接口的匿名内部类方式实现
     */
    @Test
    public void testSelect1() throws Exception{
        // 创建一个 QueryRunner 对象,传入一个数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句查询数据,并将结果集封装到 list 集合中返回
        List<User> list = queryRunner.query("select * from users", new ResultSetHandler<List<User>>() {
            // 当 query 方法执行 select 语句后,将结果集以参数的形式传入到 handle 方法中;
            @Override
            public List<User> handle(ResultSet resultSet) throws SQLException {
                // 将 结果集中的数据封装到 list 集合中
                List<User> list = new ArrayList<>();
                while(resultSet.next()){
                    User user = new User();
                    user.setId(resultSet.getInt("id"));
                    user.setUsername(resultSet.getString("username"));
                    user.setPassword(resultSet.getString("password"));
                    list.add(user);
                }
                // 返回 list 集合
                return list;
            }
        });

        // 输出 list 集合中的数据
        for (User user : list) {
            System.out.println(user);
        }
    }

    /*************************************************
    ResultSetHandler 接口定义 select 操作后怎样封装结果集,可以使用下面几个已经实现了该接口的类 更方便的封装结果集:
        1、BeanListHandler:该类会自动 将结果集封装到 list 集合中;
        2、ArrayHandler:该类适合只获取 1 条记录,把该记录每列的值封装到 object[] 数组中;
            如果 sql 语句没有带条件,能够查询到多条记录,则 ArrayHandler 只封装查询到的第一条记录;
        3、ArrayListHandler:获取多条数据,先将每条记录的每列值封装到一个 object[] 数组中,然后再将数组封装到一个 list 集合中;
        4、ColumnListHandler:获取某一列的数据,并将数据封装到 list 中;
        5、MapHandler:适合获取1条记录,把查询到的列名和列值封装到 Map 中;
            如果 sql 语句能够查到多条数据,那么 MapHandler 也只会封装第一条数据;
        6、KeyedHandler:获取多条记录,把每一条记录封装到一个 Map 中,再把这个 Map 封装到另一个 Map 中,key 为指定的字段值;
        7、MapListHandler:获取多条记录,把每条记录封装到一个 Map 中,然后再把这个 Map 封装到 List 集合中;
        8、ScalarHandler:适合获取单行单列数据;
     *************************************************/

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  1、使用 BeanListHandler 类实现,该类会自动 将结果集封装到 list 集合中
     */
    @Test
    public void testSelect2() throws Exception{
        // 创建 QueryRunner 对象,传入一个 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 SQL 语句查询数据,并将结果集封装到 list 集合中;泛型和参数类型为 Javabean 类;
        List<User> list = queryRunner.query("select * from users", new BeanListHandler<User>(User.class));

        // 输出 list 集合中的数据
        for (User user : list) {
            System.out.println(user);
        }


        // 执行 sql 语句,查询数据,并将结果集封装到 list 集合中,传入参数
        // 接收参数的 query 方法定义:query(String sql, ResultSetHandler<T> rsh, Object... params);
        // 最后一个参数 Object... 表示是可变参数,是需要传入到参数 1 的 sql 语句中的值;
        List<User> list2 = queryRunner.query("select * from users where username=? and password=?", new BeanListHandler<User>(User.class), "rose6", "126");

        // 输出 list2 集合中的数据
        for (User user : list2) {
            System.out.println(user);
        }
    }

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  2、使用 ArrayHandler 类实现:只取 1 条记录,把该记录每列的值封装到 object[] 数组中
     */
    @Test
    public void testSelect3() throws Exception{
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,查询数据
//        Object[] arr = queryRunner.query("select * from users where id=?", new ArrayHandler(), 3);

        // 如果 sql 语句不写条件,则只取第一条记录
        Object[] arr = queryRunner.query("select * from users", new ArrayHandler());

        // 遍历数组中 每列的值
        for (Object obj : arr) {
            System.out.print(obj + ",");
        }
        System.out.println();
    }

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  3、使用 ArrayListHandler 类实现:
     *      取多条数据,先将每条记录的每列值封装到一个 object[] 数组中,然后再将数组封装到一个 list 集合中
     */
    @Test
    public void testSelect4() throws Exception{
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,查询数据
        List<Object[]> list = queryRunner.query("select * from users", new ArrayListHandler());

        // 遍历结果
        for (Object[] arr : list) {     // list 集合中封装的是 object[] 数组
            for (Object obj : arr) {    // object[] 数组中封装的是 每条记录的 每列的值
                System.out.print(obj + ",");
            }
            System.out.println();
        }
    }

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  4、使用 ColumnListHandler 类实现:
     *      获取某一列的数据,并封装到 list 集合中;
     */
    @Test
    public void testSelect5() throws Exception{
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,查询数据
        // 不指定列的时候,默认获取第一列的数据
        List<Object> list1 = queryRunner.query("select * from users", new ColumnListHandler<Object>());
        System.out.println(list1);

        // 可以指定列的序号:获取 第2列 的数据
        List<Object> list2 = queryRunner.query("select * from users", new ColumnListHandler<Object>(2));
        System.out.println(list2);

        // 也可以指定列的名字:获取 username 列的数据
        List<String> list3 = queryRunner.query("select * from users", new ColumnListHandler<String>("username"));
        System.out.println(list3);
    }

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  5、使用 MapHandler 类实现:
     *      适合获取1条记录,把查询到的列名和列值封装到 Map 中
     */
    @Test
    public void testSelect6() throws Exception {
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,查询数据;只封装第一条数据
        Map<String, Object> map = queryRunner.query("select * from users", new MapHandler());

        // 遍历:key 为列名,value 为列值
        for (Map.Entry<String, Object> m : map.entrySet()) {
            System.out.println(m.getKey() + "=" + m.getValue());
        }
    }

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  6、使用 KeyedHandler 类实现:
     *      获取多条记录,每一条记录封装到一个 Map 中,再把这个 Map 封装到另一个 Map 中,key 为指定的字段值;
     */
    @Test
    public void testSelect7() throws Exception {
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,查询数据
        // 外层 Map 的 key 是第一列的值,所以是 Object 类型(不确定);内层 Map 的 key 是表的列名,所以是 String 类型(列名只能是字符串);
        Map<Object, Map<String, Object>> map = queryRunner.query("select * from users", new KeyedHandler<Object>());

        // 遍历
        for (Map.Entry<Object, Map<String, Object>> mapEntry : map.entrySet()) {
            // 外层 Map 的 key 就是 id 列的值
            System.out.println("id: " + mapEntry.getValue());
            // 外层 Map 的 value,也就是内层 Map,封装的就是 一条记录数据
            for (Map.Entry<String, Object> m : mapEntry.getValue().entrySet()) {
                // 内层 Map 就是一条记录:key 就是列名,value 就是列值
                System.out.println(m.getKey() + "=" + m.getValue());
            }
            System.out.println("-----------------");
        }
    }

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  7、使用 MapListHandler 类实现:
     *      适合获取多条记录,把每条记录封装到 Map 中,然后再把 Map 封装到 List 集合中;
     */
    @Test
    public void testSelect8() throws Exception {
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,查询数据;
        List<Map<String, Object>> list = queryRunner.query("select * from users", new MapListHandler());

        // 遍历:
        for (Map<String, Object> map : list) {
            for (Map.Entry<String, Object> m : map.entrySet()) {
                System.out.println(m.getKey() + "=" + m.getValue());
            }
            System.out.println("----------------------");
        }
    }

    /**
     * DbUtils 执行 sql 语句,查询数据
     *  8、使用 ScalarHandler 类实现:
     *      适合获取单行单列数据;
     */
    @Test
    public void testSelect9() throws Exception {
        // 创建 QueryRunner 对象,传入 数据库连接池
        QueryRunner queryRunner = new QueryRunner(C3P0Utils.getDataSource());

        // 执行 sql 语句,查询数据;
        // 默认获取 第一行第一列
        Object query = queryRunner.query("select * from users", new ScalarHandler<>());
        System.out.println(query);

        // 获取 第一行第二列
        Object query2 = queryRunner.query("select * from users", new ScalarHandler<>(2));
        System.out.println(query2);

        // 获取 第一行 password 列
        Object query3 = queryRunner.query("select * from users", new ScalarHandler<>("password"));
        System.out.println(query3);
    }
}

其中 C3P0Utils.java:

package com.jdbc.dbutils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import javax.sql.DataSource;

import com.mchange.v2.c3p0.ComboPooledDataSource;

public class C3P0Utils {
    /**
     * 创建 C3P0 连接池对象(默认加载 src 下的 c3p0-config.xml 配置文件)
     */
    private static DataSource dataSource = new ComboPooledDataSource();

    /**
     * 传出 DataSource 对象
     */
    public static DataSource getDataSource() {
        return dataSource;
    }

    /**
     * 从连接池中获取一个 数据库连接对象
     */
    public static Connection getConnection() {
        try {
            return dataSource.getConnection();
        } catch (SQLException e) {
            throw new RuntimeException();
        }
    }

    /**
     * 释放资源
     */
    public static void release(Connection conn, Statement stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

其中 c3p0-config.xml:

<c3p0-config>
    <default-config>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/day17</property>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="initialPoolSize">3</property>
        <property name="maxPoolSize">10</property>
        <property name="maxIdleTime">3000</property>
    </default-config>
</c3p0-config>

其中 数据库:

其中 User.java:

package com.jdbc.dbutils;

public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                '}';
    }
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值