最近在复习泛型的知识,想起以前使用commons-dbutils的时候,觉得这个工具太厉害了。所以,试着自己瞎写看能不能模拟commons-dbutils的功能。
1、commons-dbutils的使用
1.1、commons-dbutils是用来简化JDBC的代码。下面是其简单用法:
// 增删改 QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());// 创建QueryRunner,需要提供数据库连接池对象 String sql = "insert into t_students values(?,?,?,?)";// 给出sql模板 Object[] params = { 1, "liSi", 20, "female" };// 给出sql模板的参数 qr.update(sql, params); // 查询 QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from t_student where id = ?"; Object[] params = {1}; Stu stu = qr.query(sql, new BeanHandler<Stu>(Stu.class), params); // 将结果集rs映射成javabean,要求结果集列名与javabean属性名一致
1.2、commons-dbutils的其他查询用法
* BeanListHandler的应用,它是多行处理器 - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from t_stu"; List<Stu> stuList = qr.query(sql,new BeanListHandler<Stu>(Stu.class)); * MapHandler的应用,它是单行处理器,把一行转换成一个Map对象 - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from t_stu where sid = ?"; Object[] params = {1001}; Map map = qr.query(sql,new MapHandler(), params); * MapListHandler,它是多行处理器,把每行都转换成一个Map - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select * from t_stu"; List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler()); * ScalarHandler的应用,它是单行单列时使用,最为合适 - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource()); String sql = "select count(*) from t_stu"; Object obj = qr.query(sql,new ScalarHandler());
2、模拟commons-dbutils
2.1、工具类
CommonUtils工具类的作用见我的博客:泛型的使用:封装工具类CommonUtils-把一个Map转换成指定类型的javabean对象(用到泛型)
package com.oy.type; import java.util.Map; import org.apache.commons.beanutils.BeanUtils; public class CommonUtils { // 把一个Map转换成指定类型的javabean对象 public static <T> T tobean(Map<String, ?> map, Class<T> clazz) { try { T bean = clazz.newInstance(); BeanUtils.populate(bean, map); return bean; } catch (Exception e) { throw new RuntimeException(e); } } }
JdbcUtils类是用来获取数据库连接的,用到了c3p0连接池。
package com.oy.type; import java.sql.Connection; import java.sql.SQLException; import javax.sql.DataSource; import com.mchange.v2.c3p0.ComboPooledDataSource; public class JdbcUtils { // 使用配置文件c3p0-config.xml, 放到src目录下 private static ComboPooledDataSource dataSource = new ComboPooledDataSource(); // 返回连接 public static Connection getConnection(){ try { return dataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); } return null; } // 返回连接池对象 public static DataSource getDataSource() { return dataSource; } }
c3p0-config.xml:
<?xml version="1.0" encoding="UTF-8"?> <c3p0-config> <default-config> <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_test?useUnicode=true&characterEncoding=UTF-8</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password"></property> <property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </default-config> <named-config name="name1"> <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_test</property> <property name="driverClass">com.mysql.jdbc.Driver</property> <property name="user">root</property> <property name="password">123</property> <property name="acquireIncrement">3</property> <property name="initialPoolSize">10</property> <property name="minPoolSize">2</property> <property name="maxPoolSize">10</property> </named-config> </c3p0-config>
2.2、QR类
package com.oy.type; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; import javax.sql.DataSource; public class QR<T> { private DataSource dataSource; public QR() { super(); } public QR(DataSource dataSource) { super(); this.dataSource = dataSource; } // 可以做增删改操作 public int update(String sql, Object... params) { Connection con = null; PreparedStatement pstmt = null; try { con = dataSource.getConnection(); // 通过连接池得到连接对象 pstmt = con.prepareStatement(sql);// 使用sql模板创建preparedStatement对象 initParams(pstmt, params);// 对sql语句的?赋值 return pstmt.executeUpdate(); // 执行 } catch (Exception e) { throw new RuntimeException(e); } finally { // 释放资源 try { if (pstmt != null) { pstmt.close(); } if (con != null) { con.close(); } } catch (SQLException e1) { } } } // 可以做查询操作 public T query(String sql, BeanHandler<T> rh, Object... params) { Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { con = dataSource.getConnection(); // 通过连接池得到连接对象 pstmt = con.prepareStatement(sql);// 使用sql模板创建preparedStatement对象 initParams(pstmt, params);// 对sql语句的?赋值 rs = pstmt.executeQuery(); // 执行查询,返回ResultSet对象 return rh.handle(rs);// 传入结果集rs,得到T类型的对象 } catch (Exception e) { throw new RuntimeException(e); } finally { try { if (rs != null) { rs.close(); } if (pstmt != null) { pstmt.close(); } if (con != null) { con.close(); } } catch (SQLException e) { } } } public List<T> query(String sql, BeanListHandler<T> rh, Object... params) { Connection con = null; PreparedStatement pstmt = null; ResultSet rs = null; try { con = dataSource.getConnection(); // 通过连接池得到连接对象 pstmt = con.prepareStatement(sql);// 使用sql模板创建preparedStatement对象 initParams(pstmt, params);// 对sql语句的?赋值 rs = pstmt.executeQuery(); // 执行查询,返回ResultSet对象 return rh.handle(rs);// 传入结果集rs,得到T类型的对象 } catch (Exception e) { throw new RuntimeException(e); } finally { try { if (rs != null) { rs.close(); } if (pstmt != null) { pstmt.close(); } if (con != null) { con.close(); } } catch (SQLException e) { } } } // 给sql语句的?赋值 private void initParams(PreparedStatement pstmt, Object... params) throws SQLException { if (params != null && params.length > 0) { for (int i = 0; i < params.length; i++) { pstmt.setObject(i + 1, params[i]); } } } }
2.3、BeanHandler:将查询的结果集转换成javabean
package com.oy.type; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; public class BeanHandler<T> { private Class<T> clazz; public BeanHandler(Class<T> clazz) { this.clazz = clazz; } public T handle(ResultSet rs) throws SQLException { if (!rs.next()) return null; return CommonUtils.tobean(rsToMap(rs), clazz); } private Map<String, String> rsToMap(ResultSet rs) throws SQLException { Map<String, String> map = new HashMap<String, String>(); int count = rs.getMetaData().getColumnCount(); // 获取结果集的列数 for (int i = 1; i <= count; i++) { // 循环列 String columnName = rs.getMetaData().getColumnName(i);// 获取列名 String value = rs.getString(i); // 获取结果集一行中的每一列的值 map.put(columnName, value); } return map; } }
2.4、BeanListHandler:将结果集转换成bean集合
package com.oy.type; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; public class BeanListHandler<T> { private Class<T> clazz; public BeanListHandler(Class<T> clazz) { this.clazz = clazz; } public List<T> handle(ResultSet rs) throws SQLException { List<T> list = new ArrayList<>(); Map<String, String> map = null; while (rs.next()) { // 循环行 map = new HashMap<String, String>(); int count = rs.getMetaData().getColumnCount(); // 获取结果集的列数 for (int i = 1; i <= count; i++) { // 循环列 String columnName = rs.getMetaData().getColumnName(i);// 获取列名 String value = rs.getString(i); // 获取结果集一行中的每一列的值 map.put(columnName, value); } list.add(CommonUtils.tobean(map, clazz)); } return list; } }
2.5、MapHandler:将结果集转换成Map
package com.oy.type; import java.sql.ResultSet; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; public class MapHandler { public MapHandler() {} public Map<String, String> handle(ResultSet rs) throws SQLException { if (!rs.next()) return null; return rsToMap(rs); } private Map<String, String> rsToMap(ResultSet rs) throws SQLException { Map<String, String> map = new HashMap<String, String>(); int count = rs.getMetaData().getColumnCount(); // 获取结果集的列数 for (int i = 1; i <= count; i++) { // 循环列 String columnName = rs.getMetaData().getColumnName(i);// 获取列名 String value = rs.getString(i); // 获取结果集一行中的每一列的值 map.put(columnName, value); } return map; } }
3、测试
package com.oy.type; public class Stu { private Integer id; private Integer age; private String name; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Stu [id=" + id + ", age=" + age + ", name=" + name + "]"; } }
package com.oy.type; import java.util.List; import org.junit.jupiter.api.Test; public class StuDao { QR<Stu> qr = new QR<>(JdbcUtils.getDataSource()); public Stu getStuById(Integer id) { String sql = "select * from stu where id = ?"; Object[] params = {id}; return qr.query(sql, new BeanHandler<Stu>(Stu.class), params); } public List<Stu> getStus(String ids) { String sql = "select * from stu where id in (" + ids + ")"; return qr.query(sql, new BeanListHandler<Stu>(Stu.class)); } @Test public void test1() { //System.out.println(getStuById(1)); System.out.println(getStus("1,2")); } }
来源:https://www.cnblogs.com/xy-ouyang/p/10841748.html