DBUtiles是一个很好的处理JDBC的工具类。(DbUtils is a small set of classes designed to make working with JDBC easier )

DBUtiles中的QueryRunner和ResultSetHandler的手动实现

其中比较常用的就是QueryRunner类和ResultSetHandler接口。通过它们可以很方便的实现JDBC的功能。

QueryRunner类,有四个构造方法,其中有的构造方法可以接受一个DataSource

例如:QueryRunner runner = new QueryRunner(new ComboPooledDataSource());

当我们获得QueryRunner的实例对象时,就能通过QueryRunner类的方法方便的操作数据库。QueryRunner类主要有三类方法,batch()方法,query()方法,update()方法。

例如:

  1. QueryRunner runner=new QueryRunner(new ComboPooledDataSource());
  2. runner.update("insert into account values(null,?,?)","e",888);
  3. runner.update("update account set money=0 where name=?", "e");

查询的方法稍微麻烦一点,因为我们需要对查询到的结果集进行设置。通常需要把结果集ResultSet封装到JavaBean或者集合或者数组中。

查看一个方法:  <T> T   query(String sql, ResultSetHandler<T> rsh, Object... params)

这里第一个参数是sql语句字符串,第二个参数是一个实现了ResultSetHandler接口的类对象,第三个参数是Object类型的可变参数。返回值是一个T类型。

如果我们用的eclipse或者MyEclipse 鼠标放到ResutlSetHandlet上面,按F2,会有针对T的说明。<T> the target type the input ResultSet will be converted to.

意思是,T 代表 ResultSet结果集要装入的目标类型。也就是我们前面提到的数组,集合,甚至javabean.

下面用一段代码来实现把结果集装入一个List数组中。其中Account是一个javaBean,符合account表。

  1. public static List test2() throws Exception{
  2. QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
  3. return runner.query("select * from account where name=?",new ResultSetHandler<List<Account>>(){
  4. public List<Account> handle(ResultSet rs) throws SQLException {
  5. List<Account> list = new ArrayList<Account>();
  6. while(rs.next()){
  7. Account acc = new Account();
  8. acc.setId(rs.getInt("id"));
  9. acc.setName(rs.getString("name"));
  10. acc.setMoney(rs.getDouble("money"));
  11. list.add(acc);
  12. }
  13. return list;
  14. }
  15. } , "a");
  16. }

接下来,我们用两段代码来模拟QueryRunner和ResultSetHandler的实现原理。

  1. package cn.itheima.dbutils;
  2. import java.sql.Connection;
  3. import java.sql.ParameterMetaData;
  4. import java.sql.PreparedStatement;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.util.ArrayList;
  8. import java.util.List;
  9. import javax.sql.DataSource;
  10. import cn.itheima.domain.Account;
  11. import com.mchange.v2.c3p0.ComboPooledDataSource;
  12. public class MyQueryRunner {
  13. private DataSource source = null;
  14. public MyQueryRunner(DataSource source) {
  15. this.source = source;
  16. }
  17. //查询原理:利用MyResourceHandler处理利用sql和objs拼写出来的sql语句查询出来的resultSet,处理
  18. public <T> T query(String sql,MyResultSetHandler<T> handler,Object ...objs){
  19. Connection conn = null;
  20. PreparedStatement ps = null;
  21. ResultSet rs = null;
  22. try {
  23. conn = source.getConnection();
  24. ps = conn.prepareStatement(sql);
  25. ParameterMetaData metaData = ps.getParameterMetaData();
  26. for(int i=1;i<=metaData.getParameterCount();i++){
  27. ps.setObject(i, objs[i-1]);
  28. }
  29. rs = ps.executeQuery();
  30. return handler.handle(rs);
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. throw new RuntimeException();
  34. } finally {
  35. if (rs != null) {
  36. try {
  37. rs.close();
  38. } catch (SQLException e) {
  39. e.printStackTrace();
  40. } finally {
  41. rs = null;
  42. }
  43. }
  44. if (ps != null) {
  45. try {
  46. ps.close();
  47. } catch (SQLException e) {
  48. e.printStackTrace();
  49. } finally {
  50. ps = null;
  51. }
  52. }
  53. if (conn != null) {
  54. try {
  55. conn.close();
  56. } catch (SQLException e) {
  57. e.printStackTrace();
  58. } finally {
  59. conn = null;
  60. }
  61. }
  62. }
  63. }
  64. public int update(String sql,Object ...objs){
  65. Connection conn  = null;
  66. PreparedStatement ps = null;
  67. try{
  68. conn = source.getConnection();
  69. ps = conn.prepareStatement(sql);
  70. ParameterMetaData metaData = ps.getParameterMetaData();
  71. for(int i=1;i<=metaData.getParameterCount();i++){
  72. ps.setObject(i, objs[i-1]);
  73. }
  74. return ps.executeUpdate();
  75. }catch (Exception e) {
  76. e.printStackTrace();
  77. throw new RuntimeException();
  78. }finally{
  79. if(ps!=null){
  80. try {
  81. ps.close();
  82. } catch (SQLException e) {
  83. e.printStackTrace();
  84. }finally{
  85. ps = null;
  86. }
  87. }
  88. if(conn!=null){
  89. try {
  90. conn.close();
  91. } catch (SQLException e) {
  92. e.printStackTrace();
  93. }finally{
  94. conn = null;
  95. }
  96. }
  97. }
  98. }
  99. }

MyResultSetHandler接口

  1. package cn.itheima.dbutils;
  2. import java.sql.ResultSet;
  3. import java.sql.SQLException;
  4. public interface  MyResultSetHandler <T>{
  5. T handle(ResultSet rs)throws SQLException;
  6. }

当然,实际应用中没有这么麻烦。因为DBUtils已经帮我们实现了很多ResultSetHandler的实现类。通过这些类可以很方便的对结果集进行封装。

ResultSetHandler的实现类

    1. //1.ArrayHandler 将查询结果每一行转换为一个数组对象返回
    2. //ResultSetHandler implementation that converts a ResultSet into an Object[]. This class is thread safe.
    3. Object[] objs = runner.query("select * from account where name=?",new ArrayHandler() , "c");
    4. System.out.println(objs);
    5. //2.ArrayListHandler 将查询结果的每一行转换为一个Object[]数组,然后装入一个ArrayList集合
    6. //ResultSetHandler implementation that converts the ResultSet into a List of Object[]s. This class is thread safe.
    7. List<Object[]> list = runner.query("select * from account",new ArrayListHandler() );
    8. System.out.println(list);
    9. //手动实现ArrayListHandler的功能
    10. public static List test2() throws Exception{
    11. QueryRunner runner = new QueryRunner(new ComboPooledDataSource());
    12. return runner.query("select * from account where name=?",new ResultSetHandler<List<Account>>(){
    13. public List<Account> handle(ResultSet rs) throws SQLException {
    14. List<Account> list = new ArrayList<Account>();
    15. while(rs.next()){
    16. Account acc = new Account();
    17. acc.setId(rs.getInt("id"));
    18. acc.setName(rs.getString("name"));
    19. acc.setMoney(rs.getDouble("money"));
    20. list.add(acc);
    21. }
    22. return list;
    23. }
    24. } , "a");
    25. }
    26. //3.BeanHandler,将查询结果的第一行转换为一个JavaBean对象返回
    27. //ResultSetHandler implementation that converts the first ResultSet row into a JavaBean. This class is thread safe.
    28. Account acc = runner.query("select * from account where name=?",new BeanHandler<Account>(Account.class) , "c");
    29. System.out.println(acc);
    30. //4.BeanListHandler:将结果集中的每一行数据都封装到一个对应的JavaBean实例中,存放到List里。
    31. //ResultSetHandler implementation that converts a ResultSet into a List of beans. This class is thread safe.
    32. List<Account> acclist = runner.query("select * from account",new BeanListHandler<Account>(Account.class) );
    33. System.out.println(acclist);
    34. //5.MapHandler:将结果集中的第一行数据封装到一个Map里,key是列名,value就是对应的值。
    35. //ResultSetHandler implementation that converts the first ResultSet row into a Map. This class is thread safe.
    36. Map map = runner.query("select * from account",new MapHandler() );
    37. System.out.println(map);
    38. //6.MapListHandler:将结果集中的每一行数据都封装到一个Map里,然后再存放到List
    39. //ResultSetHandler implementation that converts a ResultSet into a List of Maps. This class is thread safe
    40. List<Map<String, Object>> maplist = runner.query("select * from account",new MapListHandler() );
    41. System.out.println(maplist);
    42. //7.ColumnListHandler:将结果集中某一列的数据存放到List中。
    43. //ResultSetHandler implementation that converts one ResultSet column into a List of Objects. This class is thread safe.
    44. List<Object> columnList = runner.query("select * from account",new ColumnListHandler(2) );
    45. System.out.println(columnList);
    46. //8.KeyedHandler(name):将结果集中的每一行数据都封装到一个Map里(List<Map>),再把这些map再存到一个map里,其key为指定的列。
    47. //ResultSetHandler implementation that returns a Map of Maps. ResultSet rows are converted into Maps which are then stored in a Map under the given key.
    48. Map<Object, Map<String, Object>> keymap = runner.query("select * from account",new KeyedHandler("id") );
    49. System.out.println(keymap);
    50. //9.ScalarHandler: 单值查询
    51. //ResultSetHandler implementation that converts one ResultSet column into an Object. This class is thread safe.
    52. //select count(*) from account;
    53. Long count = (Long)runner.query("select count(*) from account",new ScalarHandler(1) );
    54. System.out.println(count);

DBUtiles中的简单使用(QueryRunner和ResultSetHandler的手动实现)的更多相关文章

  1. Java中的简单工厂模式

    举两个例子以快速明白Java中的简单 工厂模式: 女娲抟土造人话说:“天地开辟,未有人民,女娲抟土为人.”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的思想里面.女娲造人,这就 ...

  2. iOS中XMPP简单聊天实现 好友和聊天

    版权声明本文由陈怀哲首发自简书:http://www.jianshu.com/users/9f2e536b78fd/latest_articles;微信公众号:陈怀哲(chenhuaizhe2016) ...

  3. WebSocket在ASP.NET MVC4中的简单实现

    WebSocket在ASP.NET MVC4中的简单实现 2013-12-21 20:48 by 小白哥哥, 810 阅读, 3 评论, 收藏, 编辑 WebSocket 规范的目标是在浏览器中实现和 ...

  4. Hangfire在ASP.NET CORE中的简单实现

    hangfire是执行后台任务的利器,具体请看官网介绍:https://www.hangfire.io/ 新建一个asp.net core mvc 项目 引入nuget包 Hangfire.AspNe ...

  5. 通过DFS求解有向图(邻接表存储)中所有简单回路

    前言 查阅了网上许多关于通过DFS算法对有向图中所有简单回路的查找,发现有很多关于使用DFS求解有向回路中所有简单回路的帖子,(在按照节点编号情况下)但大多数仅仅寻找了编号递增的回路.又或者未对结果去 ...

  6. Java中的简单工厂模式(转)

    Java中的简单工厂模式 举两个例子以快速明白Java中的简单工厂模式: 女娲抟土造人话说:“天地开辟,未有人民,女娲抟土为人.”女娲需要用土造出一个个的人,但在女娲造出人之前,人的概念只存在于女娲的 ...

  7. 在商城系统中使用设计模式----简单工厂模式之在springboot中使用简单工厂模式

    1.前言: 不了解简单工厂模式请先移步:在商城中使用简单工厂.在这里主要是对springboot中使用简单工厂模式进行解析. 2.问题: 什么是简单工厂:它的实现方式是由一个工厂类根据传入的参数,动态 ...

  8. flask中的简单的前端写入

    那么flask这个框架是web开发,那么肯定离不开前端的一些代码,那么python用的web开发框架 开发所用的前端模板就是jinja2模板.相对于jinja1比起来性能做到了很大的提升,那么Vue一 ...

  9. Dingo Api 1.0在laravel5.2中的简单应用

    Dingo Api是为基于laravel的开发提供了一系列工具集,这些工具集可以帮助开发者快速构建API.Dingo Api最新的版本是2.0.0-alpha1,这个版本需要php7.0以上的php版 ...

随机推荐

  1. Linux命令之paste

    介绍 cut用来从文本文件或标准输出中抽取数据列或者域,然后再用paste可以将这些数据粘贴起来形成相关文件.粘贴两个不同来源的数据时,首先需将其分类,并确保两个文件行数相同. paste将按行将不同 ...

  2. ubuntu16.04 一些简单软件安装操作

    1.ubuntu下的python指令指向python3.5(默认是指向python2.7) /usr/bin目录下 sudo ln -sf ./python3.5 ./python 2.安装pycha ...

  3. 山石防火墙debug

    debug dp basic debug dp snoop debup dp drop debug dp filter src-ip ? show logging debug

  4. 《从零开始学Swift》学习笔记(Day 52)——Cocoa错误处理模式

    原创文章,欢迎转载.转载请注明:关东升的博客 Swift错误处理模式,在Swift 1.x和Swift 2.0是不同的两种模式. Swift 1.x代码错误处理模式采用Cocoa框架错误处理模式,到现 ...

  5. EasyDSS流媒体服务器软件支持HTTPS-启用https服务申请免费证书

    EasyDSS流媒体服务器软件,提供一站式的转码.点播.直播.时移回放服务,极大地简化了开发和集成的工作. 其中,点播功能主要包含:上传.转码.分发.直播功能,主要包含:直播.录像, 直播支持RTMP ...

  6. EasyNVR摄像机无插件直播进行摄像机云台控制的接入及调用详解

    EasyNVR云台接入及控制详解 摄像机云台控制在摄像机当中很常见摄像机能将当前状态下云台的水平角度.倾斜角度和摄像机镜头焦距等位置参数存储到设备中,需要时可以迅速调用这些参数并将云台和摄像头调整至该 ...

  7. 20160916-3:mysql主从复制

    一.什么是主从复制 将一个数据库节点的数据拷贝到一个或多个数据库节点(主节点—>从节点) 二.主从复制的原理 [简述]:将主节点上的变更操作存储到binlog,从节点建立了到主节点的复制关系后, ...

  8. 超出字数部分省略(主要解决不兼容;display: -webkit-box;的浏览器)

    注明:内容于http://www.cnblogs.com/chentongtong/p/5474553.html进一步整理. 1.现webkit内核的浏览器支持display: -webkit-box ...

  9. 解决Raize日历控件显示的问题

    解决Raize日历控件显示的问题 近自己的程序被测试人员发现一个小问题,就是程序中的日历选择框,显示中的“星期一.星期二....”都显示成了“星.....”,我自己看了代码,原来是raize的控件问题 ...

  10. while循环。for循环

    1.while循环 基本循环格式 while 条件 : # 循环体 # 如果条件为真,那么循环体则执行 # 如果条件为假,那么循环体不执行 break:退出本层循环. continue:退出本次循环, ...