MYSQL 之 JDBC(十六): DBUtils

DBUtils是Apache组织提供的一个开源的JDBC工具类库,能极大简化jdbc编码的工作量

API介绍

  • QueryRunner
  • ResultSetHandler
  • 工具类DbUtils

用DBUtils进行增删改查操作:update

查的操作要使用QueryRunner

  自定义返回值的操作:MyResultSetHandler
  返回一个类的操作(单条记录):BeanHandler
  返回一个类的操作(多条记录):BeanListHandler
  返回一个Map的操作(单条记录):MapHandler
  返回多个Map的操作(多条记录):MapListHandler
  返回一个值的操作(单行单列):ScalarHandler

代码

package com.litian.jdbc;

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

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: DBUtilsTest.java
 * @time: 2020/4/7 12:09
 * @desc: |测试DBUtils工具类
 */

public class DBUtilsTest {
    public static void main(String[] args) {
        // testUpdate();
        // testQuery();
        // testBeanHanlder();
        // testBeanListHanlder();
        // testMapHanlder();
        // testMapListHanlder();
        testScalarHanlder();
    }

    /**
     * ScalarHandler:把结果集转为一个数值(可以是任意基本数据类型和字符串)
     * 默认返回第1列第1行的值,所以多行多列也就返回第一个值
     */
    public static void testScalarHanlder() {
        // 1. 创建QueryRunner的实现类
        QueryRunner qr = new QueryRunner();
        Connection conn = null;
        try {
            conn = JDBCTools.getDSConnection();
            String sql = "select username from t_user where id > ? && id < ?";
            Object result = qr.query(conn, sql, new ScalarHandler(), 2, 5);
            System.out.println(result);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }

    /**
     * MapListHandler:将结果集转为一个Map的list
     * Map对应查询的一条记录:键:sql查询的列名(不是列的别名),值:列的值。
     * 而MapListHandler:返回的是多条记录对应的Map的集合。
     */
    public static void testMapListHanlder() {
        // 1. 创建QueryRunner的实现类
        QueryRunner qr = new QueryRunner();
        Connection conn = null;
        try {
            conn = JDBCTools.getDSConnection();
            String sql = "select id, username, pwd from t_user where id > ? && id < ?";
            List<Map<String, Object>> u = qr.query(conn, sql, new MapListHandler(), 2, 5);
            System.out.println(u);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }

    /**
     * MapHandler:返回sql对应的第一条记录对应的Map对象
     * 键:sql查询的列名(不是列的别名),值:列的值。
     */
    public static void testMapHanlder() {
        // 1. 创建QueryRunner的实现类
        QueryRunner qr = new QueryRunner();
        Connection conn = null;
        try {
            conn = JDBCTools.getDSConnection();
            String sql = "select id, username, pwd from t_user where id > ? && id < ?";
            Map<String, Object> u = qr.query(conn, sql, new MapHandler(), 2, 5);
            System.out.println(u);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }

    /**
     * BeanListHandler:把结果集转为一个List,该List不为null,但可能为空集合(size()方法返回0)
     * 若sql语句的确能够查询到记录,List中存放创建BeanListHandler传入的Class对象对应的对象。
     */
    public static void testBeanListHanlder() {
        // 1. 创建QueryRunner的实现类
        QueryRunner qr = new QueryRunner();
        Connection conn = null;
        try {
            conn = JDBCTools.getDSConnection();
            String sql = "select id, username, pwd from t_user where id > ? && id < ?";
            List<User> u = (List<User>) qr.query(conn, sql, new BeanListHandler(User.class), 2, 5);
            System.out.println(u);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }

    /**
     * BeanHandler:把结果集的第一条记录转为创建BeanHandler对象时传入的Class参数对应的对象。
     */
    public static void testBeanHanlder() {
        // 1. 创建QueryRunner的实现类
        QueryRunner qr = new QueryRunner();
        Connection conn = null;
        try {
            conn = JDBCTools.getDSConnection();
            String sql = "select id, username, pwd from t_user where id = ?";
            User u = (User) qr.query(conn, sql, new BeanHandler(User.class), 3);
            System.out.println(u);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }

    /**
     * QueryRunner的query方法的返回值屈居于其ResultSetHandler参数的handle方法的返回值
     */
    public static void testQuery() {

        // 1. 创建QueryRunner的实现类
        QueryRunner qr = new QueryRunner();

        Connection conn = null;
        try {
            conn = JDBCTools.getDSConnection();
            String sql = "select id, username, pwd from t_user";
            Object obj = qr.query(conn, sql, new MyResultSetHandler());
            System.out.println(obj);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }

    }

    /**
     * 测试QueryRunner类的update方法
     * 该方法可用于insert、update和delete
     */
    public static void testUpdate() {
        // 1. 创建QueryRunner的实现类
        QueryRunner qr = new QueryRunner();
        // 2. 使用update方法
        String sql = "delete from t_user where id in (?, ?)";

        Connection conn = null;

        try {
            conn = JDBCTools.getDSConnection();
            qr.update(conn, sql, 1, 2);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }

    // 静态内部类
    static class MyResultSetHandler implements ResultSetHandler {

        @Override
        public Object handle(ResultSet resultSet) throws SQLException {
            // System.out.println("handle。。。");
            // return "111";
            List<User> us = new ArrayList<>();
            while (resultSet.next()) {
                Integer id = resultSet.getInt(1);
                String username = resultSet.getString(2);
                String pwd = resultSet.getString(3);

                User u = new User(id, username, pwd, new Date(System.currentTimeMillis()), new Timestamp(System.currentTimeMillis()));
                us.add(u);
            }
            return us;
        }
    }
}
View Code

使用DBUtils编写通用的DAO(讲道理这波我是没看懂的,DBUtils直接用不香吗)

代码实现

  • DAO接口

package com.litian.jdbc;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: DBUtilsDAO.java
 * @time: 2020/4/8 10:56
 * @desc: |访问数据的DAO接口
 * 里面定义好访问数据表的各种方法
 * T 是DAO处理的实体类的类型
 */

public interface DBUtilsDAO<T> {

    /**
     * 批量处理的方法
     *
     * @param conn
     * @param sql
     * @param args 填充占位符的Object[] 类型的可变参数
     */
    void batch(Connection conn, String sql, Object[]... args);

    /**
     * 返回具体的一个值,例如总人数,平均工资,某一个人的email等。
     *
     * @param conn
     * @param sql
     * @param args
     * @param <E>
     * @return
     */
    <E> E getForValue(Connection conn, String sql, Object... args);

    /**
     * 返回T的一个集合
     *
     * @param conn
     * @param sql
     * @param args
     * @return
     */
    List<T> getForList(Connection conn, String sql, Object... args);

    /**
     * 返回一个T的对象
     *
     * @param conn
     * @param sql
     * @param args
     * @return
     */
    T get(Connection conn, String sql, Object... args) throws SQLException;


    /**
     * insert update delete
     *
     * @param conn 数据库连接
     * @param sql  sql语句
     * @param args 填充占位符的可变参数
     */
    void update(Connection conn, String sql, Object... args);
}
View Code

DAO接口的具体实现(以get方法为例)

package com.litian.jdbc;

import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;

import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;

/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: JdbcDaoImpl.java
 * @time: 2020/4/8 11:07
 * @desc: |使用QueryRunner提供其具体的实现
 * <T>为子类需传入的泛型类型
 */

public class JdbcDaoImpl<T> implements DBUtilsDAO {

    private QueryRunner qr = null;
    private Class<T> type;

    public JdbcDaoImpl(){
        qr = new QueryRunner();
        type = ReflectionUtils.getSuperClassGenricType(getClass());
    }

    @Override
    public void batch(Connection conn, String sql, Object[]... args) {

    }

    @Override
    public List getForList(Connection conn, String sql, Object... args) {
        return null;
    }

    @Override
    public Object get(Connection conn, String sql, Object... args) throws SQLException {
        return qr.query(conn, sql, new BeanHandler<>(type), args);
    }

    @Override
    public void update(Connection conn, String sql, Object... args) {

    }

    @Override
    public Object getForValue(Connection conn, String sql, Object... args) {
        return null;
    }
}
View Code

一个继承上面实现的子类,虽然啥也没写,但是方便以后扩展

package com.litian.jdbc;


/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: UserDao.java
 * @time: 2020/4/8 11:08
 * @desc: |
 */

public class UserDao extends JdbcDaoImpl<User> {
}

使用上面这个子类,看看能否完成DAO的功能

package com.litian.jdbc;

import java.sql.Connection;

/**
 * @author: Li Tian
 * @contact: litian_cup@163.com
 * @software: IntelliJ IDEA
 * @file: UserDaoTest.java
 * @time: 2020/4/8 11:10
 * @desc: |
 */

public class UserDaoTest {

    UserDao ud = new UserDao();

    public static void main(String[] args){
        new UserDaoTest().testGet();
    }

    public void testGet(){
        Connection conn = null;
        try {
            conn = JDBCTools.getDSConnection();
            String sql = "select id, username, pwd from t_user where id = ?";
            User u = (User) ud.get(conn, sql, 3);
            System.out.println(u);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCTools.release(null, null, conn);
        }
    }
}
View Code


————————————————
版权声明:本文为CSDN博主「李英俊小朋友」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_21579045/article/details/105386353

原文地址:https://www.cnblogs.com/qiu-hua/p/13199856.html