Skip to content

commons-dbutils

1. commons-dbutils介绍

commons-dbutils是一个简化JDBC操作的Java工具包,它提供了一组数据库操作辅助类,能够极大地减少代码量,提高开发效率。该项目属于Apache Commons组件库的一部分,以提供简单的数据库访问API为核心,通过简单的抽象,隐藏了JDBC的复杂性,但同时保留了强大的功能。

2. 核心组件

在项目结构上,commons-dbutils主要包括以下几个核心组件:

  • QueryRunner:核心类,提供简化执行SQL查询和更新的方法。
  • ResultSetHandler:结果集处理器,定义了处理查询结果的标准接口。

3. maven中使用commons-dbutils

  1. 首先添加maven依赖:
xml
<dependency>
    <groupId>commons-dbutils</groupId>
    <artifactId>commons-dbutils</artifactId>
    <version>1.8.1</version>
</dependency>

4. 使用QueryRunner

使用QueryRunner类,开发人员可以避免直接与JDBC打交道,减少了那些重复的模板代码。它支持两种类型的构造器:

  • 无参构造器:用户需要手动提供Connection对象来执行数据库操作。
  • 带DataSource参数构造器:可以直接利用DbUtils提供的自动关闭连接的功能,无需手动管理Connection的生命周期。
java
public static void main(String[] args) throws Exception {
    String jdbcUrl ="";
    String username ="";
    String password ="";
    Class.forName("com.mysql.cj.jdbc.Driver");
    // 创建Connection实例
    Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
    QueryRunner qr = new QueryRunner();
    // 1. 查询集合
    String querySql = "select * from t_user where name like ? limit 10;"
    Object[] params = new Object[]{"张%"};
    List<User> userList = qr.execute(conn, querySql, new BeanHandler<>(User.class), params);
    // 2. 查询单个对象
    String queryOneSql = "select * from t_user limit 1;"
    User user = qr.query(conn, querySql, new BeanHandler<>(User.class));
    // 3. 查询count
    String queryCountSql = "select count(*) from t_user;"
    // 1表示取结果集中第一列
    Integer rows = qr.query(conn, queryCountSql, new ScalarHandler<Integer>(1));
    // 4. 插入和更新, 返回行数
    String executeSql = "insert into t_user values('jack')"
    int rowCount = qr.execute(conn, executeSql);
}

5. 数据类型转换

commons-dbutils提供了强大的类型转换机制,可以通过自定义转换器或者使用默认的转换规则来处理数据类型转换。下面展示了如何自定义一个日期类型的转换器,以处理从VARCHAR到LocalDateTime的转换:

java
public class CustomTypeConverter implements TypeConverter {
    @Override
    public <T> T convert(Class<T> type, ResultSet rs, int column, Statement stmt, Connection conn) throws SQLException {
        String dateString = rs.getString(column);
        if (type.isAssignableFrom(LocalDateTime.class) && dateString != null) {
            // 自定义日期格式转换逻辑
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            return (T) LocalDateTime.parse(dateString, formatter);
        }
        return null;
    }
}
 
// 注册自定义转换器
DbUtils.setCustomTypeConverter(new CustomTypeConverter());
 
// 使用转换后的数据类型进行查询
try {
    QueryRunner queryRunner = new QueryRunner(DataSourceUtils.getDataSource());
    List<SomeObject> someObjects = queryRunner.query(conn, "SELECT datetime_column FROM some_table", new BeanListHandler<>(SomeObject.class));
    // 此处SomeObject类中有一个LocalDateTime类型的属性
    for (SomeObject obj : someObjects) {
        System.out.println(obj.getDateTimeColumn().toString()); // 输出转换后的日期时间
    }
} catch (SQLException e) {
    e.printStackTrace();
}

6. 封装工具类

java
public class JdbcUtil {

    static Logger logger = LoggerFactory.getLogger(JdbcUtil.class);

    public static Connection getConnection(String jdbcUrl, String username, String password) throws SQLException {

        if (jdbcUrl.contains("mysql")) {
            // 加载驱动
            DbUtils.loadDriver("com.mysql.cj.jdbc.Driver");
        }
        // 创建Connection实例
        Connection connection = DriverManager.getConnection(jdbcUrl, username, password);
        return connection;
    }

    public static <T> List<T> queryList(Connection conn, String querySql, Class<T> clazz, Object... params) throws SQLException {
        // 创建QueryRunner实例
        QueryRunner qr = new QueryRunner();
        List<T> result = qr.execute(conn, querySql, new BeanHandler<>(clazz), params);
        return result;
    }

    // 查询多行,指定列作为key,返回Map
    public static <K, T> Map<K, T> queryBeanMap(Connection conn, String querySql, Class<T> clazz, Object... params) throws SQLException {
        // 创建QueryRunner实例
        QueryRunner qr = new QueryRunner();
        Map<K, T> result = qr.query(conn, querySql, new BeanMapHandler<K, T>(clazz), params);
        return result;
    }

    public static <T> List<Map<String, Object>> queryMapList(Connection conn, String querySql, Object... params) throws SQLException {
        // 创建QueryRunner实例
        QueryRunner qr = new QueryRunner();
        List<Map<String, Object>> result = qr.query(conn, querySql, new MapListHandler(), params);
        return result;
    }

    public static <T> T queryOne(Connection conn, String querySql, Class<T> clazz, Object... params) throws SQLException {
        // 创建QueryRunner实例
        QueryRunner qr = new QueryRunner();
        T result = qr.query(conn, querySql, new BeanHandler<>(clazz), params);
        return result;
    }

    // 查询一行单个字段,如count(*), max(id)等
    public static <T> T queryOneSingleColumn(Connection conn, String querySql, int columnIndex, Object... params) throws SQLException {
        // 创建QueryRunner实例
        QueryRunner qr = new QueryRunner();
        T result = qr.query(conn, querySql, new ScalarHandler<T>(columnIndex), params);
        return result;
    }

    // 返回影响行数
    public static int execute(Connection conn, String executeSql, Object... params) throws SQLException {
        // 创建QueryRunner实例
        QueryRunner qr = new QueryRunner();
        int rowCount = qr.execute(conn, executeSql, params);
        return rowCount;
    }

    public static void closeConnection(Connection conn) {
        DbUtils.closeQuietly(conn);
    }
}