最近在复习泛型的知识,想起以前使用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. ARM的编程模式及寄存器

    根据朱老师的课程及下面博客整理 http://blog.chinaunix.net/uid-20443992-id-5700979.html ARM 采用的是32位架构 ARM 约定: Byte : ...

  2. python_面试题_TCP的三次握手与四次挥手问题

    1.相关问题 问题1: 请详细描述三次握手和四次挥手的过程,并画出状态图 问题2: 四次挥手中TIME_WAIT状态存在的目的是什么? 问题3: TCP是通过什么机制保障可靠性的? 2.问题回答 问题 ...

  3. 前端,后端,UI,UE,UX,区别到底在哪里?

    前端后端,到低区别在哪里? 其实后端是负责更为复杂的数据逻辑,表处理结构,如何实现一连串的数据提交,包括,数据验证,数据影响,数据计算,数据提取,,,等等. 那么前端负责的是什么呢?数据展示,数据验证 ...

  4. 【VS开发】【图像处理】 bayer, yuv, RGB转换方法

    因为我的STVxxx USB camera输出格式是bayer格式,手头上只有YUVTOOLS这个查看工具,没法验证STVxxx在开发板上是否正常工作. 网上找了很久也没找到格式转换工具,最后放弃了, ...

  5. CodeSmith 找不到请求的 .Net Framework Data Provider

    连接数据库时候报标题的错误解决方案 安装mysql-connector-net-6.8.7.msi,下载地址:http://dev.mysql.com/downloads/connector/net/ ...

  6. urllib库:解析链接

    1from urllib.parse import urlparse, urlunparse, urlsplit, urlunsplit, urljoin, urlencode, parse_qs,  ...

  7. 【转】mysql索引的探究

    转自:https://mp.weixin.qq.com/s/XTu7jERv3A0CIAzlECFnlA 相信很多人对于MySQL的索引都不陌生,索引(Index)是帮助MySQL高效获取数据的数据结 ...

  8. sqlserver迁移mysql语法修改

    1.top 100  选取表中前100条改为 limit #{limit},limit 为变量2.获取当前日期getdate()改为now()3.id=#{id,jdbcType=BIGINT}改为i ...

  9. 开启linux服务器防火墙

    启用ufwsudo ufw enablesudo ufw default deny运行以上两条命令后,开启了防火墙,并在系统启动时自动开启.关闭所有外部对本机的访问,但本机访问外部正常. 开启和禁用s ...

  10. python爬虫常用第三方库

    这个列表包含与网页抓取和数据处理的Python库 网络 通用 urllib -网络库(stdlib). requests -网络库. grab – 网络库(基于pycurl). pycurl – 网络 ...