最近在复习泛型的知识,想起以前使用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. 【AI-人工智能-mmdetection】ModuleNotFoundError: No module named 'mmdet.version'

    在集成 mmdetection 框架时遇到这样的问题. ModuleNotFoundError: No module named 'mmdet.version' mmdetection 框架搭建过程很 ...

  2. zabbix4安装部署

    参考: https://www.cnblogs.com/barneywill/p/10380622.html https://www.cnblogs.com/yinzhengjie/p/1037256 ...

  3. Elasticsearch-数据的存储、搜索(干货)

    ES-深入功能ES中数据是如何组织的?逻辑设计:用于索引和搜索的基本单位是文档,可以将其认为是关系数据库里的一行.文档以类型来分组,类型包含若干文档,类似表格包含若干行.最终,一个或多个类型存在于同一 ...

  4. AppCan适配问题

    使用AppCan调试中心时,屏幕适配是个问题,经过多次调试总结出如下经验: 1,使用HD+(1560 x 720):显示错乱 2,使用FHD+ (2340 x 1080):显示错乱 3,HD (128 ...

  5. python 写简单的职员信息管理系统

    职员信息管理系统要求依次从键盘录入每位员工的信息,包括姓名.员工id.身份证号要求:1.身份证号十八位,要求除了第18位可以为x,其余都只能为数字2.id须由5位数字组成3.否则提示用户重新输入不符合 ...

  6. VeryNginx故障排除

    在安装和使用 VeryNginx 的过程中可能会遇到一些问题,下面列举了常见的问题及对应的解决方案,供参考. Q: run "python instal.py install all&quo ...

  7. cmd内部命令和外部命令的区别

    内部命令 我们可以直接在CMD下就可以执行的命令,例如:telnet.ftp.dir.cd.等等,你可以在CMD下输入help进行查看 外部命令 就是cmd下不能直接运行的命令,(例如大家常用的nc) ...

  8. qt嵌入式html和本地c++通信方式

    前沿:我们在做qt项目的时候,通常会把某个html网页直接显示到应用程序中.比如绘图.直接把html形式的图标嵌入到应用程序中 但是我们需要把数据从后台c++端传到html端,实现显示.qt实现了相关 ...

  9. Hack the box: Bastion

    介绍 目标:10.10.10.134 (Windows) Kali:10.10.16.65 In conclusion, Bastion is not a medium box. But it wou ...

  10. 日语能力考试N2级核心词汇必备—副词

                                                                         日语能力考试N2级核心词汇必备—副词 ABAB型的副词 あちこ ...