最近在复习泛型的知识,想起以前使用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&amp;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"));
}
}

泛型(三)模拟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. NOIP2013提高问题求解T2(关于递推与递归)

    同步发表于我的洛谷博客. NOIP2013提高问题求解2: 现有一只青蛙,初始时在n号荷叶上.当它某一时刻在k号荷叶上时,下一时刻将等概率地随机跳到1,2,--,k号荷叶之一上,直到跳到第1号荷叶为止 ...

  2. 简述Vue中使用Vuex

    1.为什么要用vuex 在vue组件通信的过程中,我们通信的目的往往就是在组件之间传递数据或组件的状态(这里将数据和状态统称为状态),进而更改状态.但可以看到如果我们通过最基本的方式来进行通信,一旦需 ...

  3. Windows 下 C/C++ 多线程编程入门参考范例

    #include <windows.h> #include <iostream> using namespace std; DWORD WINAPI myThread(LPVO ...

  4. Educational Codeforces Round 64 -B(贪心)

    题目链接:https://codeforces.com/contest/1156/problem/B 题意:给一段字符串,通过变换顺序使得该字符串不包含为位置上相邻且在字母表上也相邻的情况,并输出. ...

  5. 使用注解@CrossOrigin解决跨域问题

    转一个大兄弟写的贴子,总结得很好,很全面 https://www.cnblogs.com/mmzs/p/9167743.html 作者: 淼淼之森

  6. CMD 显示当前时间和日期

    1. 其实还是应该多看 help  要知道 help 比百度还用一百倍 除了 可能东西比较多 C:\Users\Administrator>date /? 显示或设置日期. DATE [/T | ...

  7. 数组遍历方法forEach 和 map 的区别

    数组遍历方法forEach 和 map 的区别:https://www.cnblogs.com/sticktong/p/7602783.html

  8. L2-001. 紧急救援(迪杰斯特拉算法)

    L2-001. 紧急救援 时间限制 200 ms 内存限制 65536 kB 代码长度限制 8000 B 判题程序 Standard 作者 陈越 作为一个城市的应急救援队伍的负责人,你有一张特殊的全国 ...

  9. 搜索专题:问题 E: 挑战ACM迷宫

    这是往年校赛的一道题,最开始做这道题的时候还没有系统的学习过搜索,用了C语言学的回溯法尝试,毫无疑问的TLE: 学习了DFS之后,自己的剪枝功力不够,又是TLE,最后学了BFS之后,哇,终于做出来了, ...

  10. sql server 对数运算函数log(x)和log10(x)

    --LOG(x)返回x的自然对数,x相对于基数e的对数 --LOG10(x)返回x的基数为10的对数 示例:select LOG(3),LOG(6),LOG10(1),LOG10(100),LOG10 ...