最近在复习泛型的知识,想起以前使用commons-dbutils的时候,觉得这个工具太厉害了。所以,试着自己瞎写看能不能模拟commons-dbutils的功能。

1、commons-dbutils的使用

  1.1、commons-dbutils是用来简化JDBC的代码。下面是其简单用法:

  1. // 增删改
  2. QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());// 创建QueryRunner,需要提供数据库连接池对象
  3. String sql = "insert into t_students values(?,?,?,?)";// 给出sql模板
  4. Object[] params = { 1, "liSi", 20, "female" };// 给出sql模板的参数
  5. qr.update(sql, params);
  6.  
  7. // 查询
  8. QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
  9. String sql = "select * from t_student where id = ?";
  10. Object[] params = {1};
  11. Stu stu = qr.query(sql, new BeanHandler<Stu>(Stu.class), params);
  12. // 将结果集rs映射成javabean,要求结果集列名与javabean属性名一致

  1.2、commons-dbutils的其他查询用法

  1. * BeanListHandler的应用,它是多行处理器
  2. - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
  3. String sql = "select * from t_stu";
  4. List<Stu> stuList = qr.query(sql,new BeanListHandler<Stu>(Stu.class));
  5. * MapHandler的应用,它是单行处理器,把一行转换成一个Map对象
  6. - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
  7. String sql = "select * from t_stu where sid = ?";
  8. Object[] params = {1001};
  9. Map map = qr.query(sql,new MapHandler(), params);
  10. * MapListHandler,它是多行处理器,把每行都转换成一个Map
  11. - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
  12. String sql = "select * from t_stu";
  13. List<Map<String,Object>> mapList = qr.query(sql, new MapListHandler());
  14. * ScalarHandler的应用,它是单行单列时使用,最为合适
  15. - QueryRunner qr = new QueryRunner(JdbcUtils.getDataSource());
  16. String sql = "select count(*) from t_stu";
  17. Object obj = qr.query(sql,new ScalarHandler());

2、模拟commons-dbutils

  2.1、工具类

  CommonUtils工具类的作用见我的博客:泛型的使用:封装工具类CommonUtils-把一个Map转换成指定类型的javabean对象(用到泛型)

  1. package com.oy.type;
  2. import java.util.Map;
  3. import org.apache.commons.beanutils.BeanUtils;
  4.  
  5. public class CommonUtils {
  6.  
  7. // 把一个Map转换成指定类型的javabean对象
  8. public static <T> T tobean(Map<String, ?> map, Class<T> clazz) {
  9. try {
  10. T bean = clazz.newInstance();
  11. BeanUtils.populate(bean, map);
  12. return bean;
  13. } catch (Exception e) {
  14. throw new RuntimeException(e);
  15. }
  16. }
  17. }

  JdbcUtils类是用来获取数据库连接的,用到了c3p0连接池。

  1. package com.oy.type;
  2. import java.sql.Connection;
  3. import java.sql.SQLException;
  4. import javax.sql.DataSource;
  5. import com.mchange.v2.c3p0.ComboPooledDataSource;
  6.  
  7. public class JdbcUtils {
  8.  
  9. // 使用配置文件c3p0-config.xml, 放到src目录下
  10. private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
  11.  
  12. // 返回连接
  13. public static Connection getConnection(){
  14. try {
  15. return dataSource.getConnection();
  16. } catch (SQLException e) {
  17. e.printStackTrace();
  18. }
  19. return null;
  20. }
  21.  
  22. // 返回连接池对象
  23. public static DataSource getDataSource() {
  24. return dataSource;
  25. }
  26. }

  c3p0-config.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <c3p0-config>
  3. <default-config>
  4. <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_test?useUnicode=true&amp;characterEncoding=UTF-8</property>
  5. <property name="driverClass">com.mysql.jdbc.Driver</property>
  6. <property name="user">root</property>
  7. <property name="password"></property>
  8. <property name="acquireIncrement">3</property>
  9. <property name="initialPoolSize">10</property>
  10. <property name="minPoolSize">2</property>
  11. <property name="maxPoolSize">10</property>
  12. </default-config>
  13. <named-config name="name1">
  14. <property name="jdbcUrl">jdbc:mysql://localhost:3306/db_test</property>
  15. <property name="driverClass">com.mysql.jdbc.Driver</property>
  16. <property name="user">root</property>
  17. <property name="password">123</property>
  18. <property name="acquireIncrement">3</property>
  19. <property name="initialPoolSize">10</property>
  20. <property name="minPoolSize">2</property>
  21. <property name="maxPoolSize">10</property>
  22. </named-config>
  23. </c3p0-config>

  2.2、QR类

  1. package com.oy.type;
  2. import java.sql.Connection;
  3. import java.sql.PreparedStatement;
  4. import java.sql.ResultSet;
  5. import java.sql.SQLException;
  6. import java.util.List;
  7. import javax.sql.DataSource;
  8.  
  9. public class QR<T> {
  10. private DataSource dataSource;
  11.  
  12. public QR() {
  13. super();
  14. }
  15.  
  16. public QR(DataSource dataSource) {
  17. super();
  18. this.dataSource = dataSource;
  19. }
  20.  
  21. // 可以做增删改操作
  22. public int update(String sql, Object... params) {
  23. Connection con = null;
  24. PreparedStatement pstmt = null;
  25. try {
  26. con = dataSource.getConnection(); // 通过连接池得到连接对象
  27. pstmt = con.prepareStatement(sql);// 使用sql模板创建preparedStatement对象
  28. initParams(pstmt, params);// 对sql语句的?赋值
  29. return pstmt.executeUpdate(); // 执行
  30. } catch (Exception e) {
  31. throw new RuntimeException(e);
  32. } finally { // 释放资源
  33. try {
  34. if (pstmt != null) {
  35. pstmt.close();
  36. }
  37. if (con != null) {
  38. con.close();
  39. }
  40. } catch (SQLException e1) {
  41. }
  42. }
  43. }
  44.  
  45. // 可以做查询操作
  46. public T query(String sql, BeanHandler<T> rh, Object... params) {
  47. Connection con = null;
  48. PreparedStatement pstmt = null;
  49. ResultSet rs = null;
  50. try {
  51. con = dataSource.getConnection(); // 通过连接池得到连接对象
  52. pstmt = con.prepareStatement(sql);// 使用sql模板创建preparedStatement对象
  53. initParams(pstmt, params);// 对sql语句的?赋值
  54. rs = pstmt.executeQuery(); // 执行查询,返回ResultSet对象
  55.  
  56. return rh.handle(rs);// 传入结果集rs,得到T类型的对象
  57. } catch (Exception e) {
  58. throw new RuntimeException(e);
  59. } finally {
  60. try {
  61. if (rs != null) {
  62. rs.close();
  63. }
  64. if (pstmt != null) {
  65. pstmt.close();
  66. }
  67. if (con != null) {
  68. con.close();
  69. }
  70. } catch (SQLException e) {
  71. }
  72. }
  73. }
  74.  
  75. public List<T> query(String sql, BeanListHandler<T> rh, Object... params) {
  76. Connection con = null;
  77. PreparedStatement pstmt = null;
  78. ResultSet rs = null;
  79. try {
  80. con = dataSource.getConnection(); // 通过连接池得到连接对象
  81. pstmt = con.prepareStatement(sql);// 使用sql模板创建preparedStatement对象
  82. initParams(pstmt, params);// 对sql语句的?赋值
  83. rs = pstmt.executeQuery(); // 执行查询,返回ResultSet对象
  84.  
  85. return rh.handle(rs);// 传入结果集rs,得到T类型的对象
  86. } catch (Exception e) {
  87. throw new RuntimeException(e);
  88. } finally {
  89. try {
  90. if (rs != null) {
  91. rs.close();
  92. }
  93. if (pstmt != null) {
  94. pstmt.close();
  95. }
  96. if (con != null) {
  97. con.close();
  98. }
  99. } catch (SQLException e) {
  100. }
  101. }
  102. }
  103.  
  104. // 给sql语句的?赋值
  105. private void initParams(PreparedStatement pstmt, Object... params) throws SQLException {
  106. if (params != null && params.length > 0) {
  107. for (int i = 0; i < params.length; i++) {
  108. pstmt.setObject(i + 1, params[i]);
  109. }
  110. }
  111. }
  112. }

  2.3、BeanHandler:将查询的结果集转换成javabean

  1. package com.oy.type;
  2. import java.sql.ResultSet;
  3. import java.sql.SQLException;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6. public class BeanHandler<T> {
  7. private Class<T> clazz;
  8.  
  9. public BeanHandler(Class<T> clazz) {
  10. this.clazz = clazz;
  11. }
  12.  
  13. public T handle(ResultSet rs) throws SQLException {
  14. if (!rs.next())
  15. return null;
  16.  
  17. return CommonUtils.tobean(rsToMap(rs), clazz);
  18. }
  19.  
  20. private Map<String, String> rsToMap(ResultSet rs) throws SQLException {
  21. Map<String, String> map = new HashMap<String, String>();
  22. int count = rs.getMetaData().getColumnCount(); // 获取结果集的列数
  23. for (int i = 1; i <= count; i++) { // 循环列
  24. String columnName = rs.getMetaData().getColumnName(i);// 获取列名
  25. String value = rs.getString(i); // 获取结果集一行中的每一列的值
  26. map.put(columnName, value);
  27. }
  28. return map;
  29. }
  30. }

  2.4、BeanListHandler:将结果集转换成bean集合

  1. package com.oy.type;
  2. import java.sql.ResultSet;
  3. import java.sql.SQLException;
  4. import java.util.ArrayList;
  5. import java.util.HashMap;
  6. import java.util.List;
  7. import java.util.Map;
  8.  
  9. public class BeanListHandler<T> {
  10. private Class<T> clazz;
  11.  
  12. public BeanListHandler(Class<T> clazz) {
  13. this.clazz = clazz;
  14. }
  15.  
  16. public List<T> handle(ResultSet rs) throws SQLException {
  17. List<T> list = new ArrayList<>();
  18. Map<String, String> map = null;
  19.  
  20. while (rs.next()) { // 循环行
  21. map = new HashMap<String, String>();
  22. int count = rs.getMetaData().getColumnCount(); // 获取结果集的列数
  23. for (int i = 1; i <= count; i++) { // 循环列
  24. String columnName = rs.getMetaData().getColumnName(i);// 获取列名
  25. String value = rs.getString(i); // 获取结果集一行中的每一列的值
  26. map.put(columnName, value);
  27. }
  28. list.add(CommonUtils.tobean(map, clazz));
  29. }
  30.  
  31. return list;
  32. }
  33. }

  2.5、MapHandler:将结果集转换成Map

  1. package com.oy.type;
  2. import java.sql.ResultSet;
  3. import java.sql.SQLException;
  4. import java.util.HashMap;
  5. import java.util.Map;
  6.  
  7. public class MapHandler {
  8.  
  9. public MapHandler() {}
  10.  
  11. public Map<String, String> handle(ResultSet rs) throws SQLException {
  12. if (!rs.next())
  13. return null;
  14. return rsToMap(rs);
  15. }
  16.  
  17. private Map<String, String> rsToMap(ResultSet rs) throws SQLException {
  18. Map<String, String> map = new HashMap<String, String>();
  19. int count = rs.getMetaData().getColumnCount(); // 获取结果集的列数
  20. for (int i = 1; i <= count; i++) { // 循环列
  21. String columnName = rs.getMetaData().getColumnName(i);// 获取列名
  22. String value = rs.getString(i); // 获取结果集一行中的每一列的值
  23. map.put(columnName, value);
  24. }
  25. return map;
  26. }
  27. }

3、测试

  1. package com.oy.type;
  2. public class Stu {
  3. private Integer id;
  4. private Integer age;
  5. private String name;
  6. public Integer getId() {
  7. return id;
  8. }
  9. public void setId(Integer id) {
  10. this.id = id;
  11. }
  12. public Integer getAge() {
  13. return age;
  14. }
  15. public void setAge(Integer age) {
  16. this.age = age;
  17. }
  18. public String getName() {
  19. return name;
  20. }
  21. public void setName(String name) {
  22. this.name = name;
  23. }
  24. @Override
  25. public String toString() {
  26. return "Stu [id=" + id + ", age=" + age + ", name=" + name + "]";
  27. }
  28.  
  29. }
  1. package com.oy.type;
  2. import java.util.List;
  3. import org.junit.jupiter.api.Test;
  4.  
  5. public class StuDao {
  6. QR<Stu> qr = new QR<>(JdbcUtils.getDataSource());
  7.  
  8. public Stu getStuById(Integer id) {
  9. String sql = "select * from stu where id = ?";
  10. Object[] params = {id};
  11. return qr.query(sql, new BeanHandler<Stu>(Stu.class), params);
  12. }
  13.  
  14. public List<Stu> getStus(String ids) {
  15. String sql = "select * from stu where id in (" + ids + ")";
  16. return qr.query(sql, new BeanListHandler<Stu>(Stu.class));
  17. }
  18.  
  19. @Test
  20. public void test1() {
  21. //System.out.println(getStuById(1));
  22. System.out.println(getStus("1,2"));
  23. }
  24. }

泛型(三)模拟commons-dbutils的更多相关文章

  1. 写一个ORM框架的第一步(Apache Commons DbUtils)

    新一次的内部提升开始了,如果您想写一个框架从Apache Commons DbUtils开始学习是一种不错的选择,我们先学习应用这个小“框架”再把源代码理解,然后写一个属于自己的ORM框架不是梦. 一 ...

  2. 高性能jdbc封装工具 Apache Commons DbUtils 1.6(转载)

    转载自原文地址:http://gao-xianglong.iteye.com/blog/2166444 前言 关于Apache的DbUtils中间件或许了解的人并不多,大部分开发人员在生成环境中更多的 ...

  3. Apache Commons DbUtils 快速上手

    原文出处:http://lavasoft.blog.51cto.com/62575/222771 Hibernate太复杂,iBatis不好用,JDBC代码太垃圾,DBUtils在简单与优美之间取得了 ...

  4. 《笔者带你剖析Apache Commons DbUtils 1.6》(转)

    前言 关于Apache的DbUtils中间件或许了解的人并不多,大部分开发人员在生成环境中更 多的是依靠Hibernate.Ibatis.Spring JDBC.JPA等大厂提供的持久层技术解决方案, ...

  5. WPF案例 (三) 模拟QQ“快速换装"界面

    原文:WPF案例 (三) 模拟QQ"快速换装"界面 这个小程序使用Wpf模拟QQ快速换装页面的动画特效,通过使用组合快捷键Ctrl+Left或Ctrl+Right,可实现Image ...

  6. java JDBC (七) org.apache.commons.dbutils 查询

    package cn.sasa.demo1; import java.sql.Connection; import java.sql.SQLException; import java.util.Li ...

  7. java JDBC (六) org.apache.commons.dbutils 增删改

    dbutils是apache封装了JDBC的工具类,比mysql-connector更方便些 下载地址:http://commons.apache.org/proper/commons-dbutils ...

  8. Java连接数据库 #04# Apache Commons DbUtils

    索引 通过一个简单的调用看整体结构 Examples 修改JAVA连接数据库#03#中的代码 DbUtils并非是什么ORM框架,只是对原始的JDBC进行了一些封装,以便我们少写一些重复代码.就“用” ...

  9. commons.dbutils 的使用列子

    c0p3的导入请参考前文 https://www.cnblogs.com/appium/p/10183016.html JdbcUtils: package cn.itcast.jdbc; impor ...

  10. java.lang.ClassNotFoundException: org.apache.commons.dbutils.QueryRunner

    七月 28, 2017 11:06:33 下午 org.apache.catalina.core.StandardWrapperValve invoke严重: Servlet.service() fo ...

随机推荐

  1. Hand on Machine Learning第三章课后作业(1):垃圾邮件分类

    import os import email import email.policy 1. 读取邮件数据 SPAM_PATH = os.path.join( "E:\\3.Study\\机器 ...

  2. HDU2196 Computer【换根dp】

    题目传送门 题意: 给定一个$N$个点的树,第$i$条边的长度是$A_i$,求每个点到其他所有点的最长距离.数据范围:$n ≤ 10000$,$A_i ≤ 10_9$ 分析 首先,从随便哪个节点($1 ...

  3. Linux系统搭建并管理Git服务器

    搭建Git服务器 GitHub就是一个免费托管开源代码的远程仓库.但是对于某些视源代码如生命的商业公司来说,既不想公开源代码,又舍不得给GitHub交保护费,那就只能自己搭建一台Git服务器作为私有仓 ...

  4. 修改Docker0网桥默认网段

    Docker--修改Docker0网桥默认网段 修改文件 /etc/docker/daemon.json 添加内容 "bip": "ip/netmask" [ ...

  5. 【转】mysql卸载(windows)

    作者:cxy_Summer 来源:CSDN 原文:https://blog.csdn.net/cxy_Summer/article/details/70142322 版权声明:本文为博主原创文章,转载 ...

  6. 一些常用的字符串函数(CLR函数)

    原代码来自:东莞--小小大神 使用 --聚合函数 SELECT father_key,dbo.String_Agg(department_name) FROM dbo.b_department GRO ...

  7. npm学习(六)之如何创建 Node.js 模块

    如何创建 Node.js 模块 Node.js 模块是一种可以发布到 npm 的包.当你创建一个新模块时,创建 package.json 文件是第一步. 你可以使用 npm init 命令创建 pac ...

  8. java 正则表达式 复习

    正则表达式在日常开发中会经常的接触到,学会了正则可以更有效的对字符进行验证.拆分.替换.判断字符串是否合法等操作... 常用语法: 字符的取值范围 1.[abc] : 表示可能是a,可能是b,也可能是 ...

  9. mysql远程连接错误10038--navicat for mysql (10038)

    1.确定3306端口是否对外开放 如果是阿里云服务器,需要添加安全组规则 2.授权 执行sql,账号密码按照自己服务器而定 grant all privileges on *.* to 'root'@ ...

  10. setTimeout定时器

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...