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; } } }
使用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); }
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; } }
一个继承上面实现的子类,虽然啥也没写,但是方便以后扩展
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); } } }