2019独角兽企业重金招聘Python工程师标准>>>

我们做过的很多项目中都会使用spring的JdbcTemplate进行结果集的查询操作,以前在使用的时候一直都是“拿来主义”,功能实现了就OK了,没有深究什么内容,特别是查询接口的回调内容方法,没有过多的研究过细节内容。最近一次使用JdbcTemplate进行查询操作,发现了一些有规律的内容,所以就深入学习了一下。和大家一起探讨一下:

对于spring的JdbcTemplate进行结果集查询操作,spring给我们开发的是一系列的query方法,这些查询的方法中回调的接口主有三种:ResultSetExtractorRowCallbackHandlerRowMapper这个内容有图有真相:

但是这三种回调接口具体的用法和区别,我们一起来看一下:

场景设定,数据库中存在T_USER表,表中存在多条数据,需要将是表中数据映射到User对象上

1、org.springframework.jdbc.core.ResultSetExtractor

     ResultSetExtractor接口中定义的方法如下:

public interface ResultSetExtractor {  Object extractData(ResultSet rs) throws SQLException,   DataAccessException;  }  

    如果使用ResultSetExtractor接口作为回调方法,查询方式如下:

List<User> userList = (List<User>)jdbcDao.getJdbcTemplate().  query("select * from T_USER", new ResultSetExtractor() {  @Override  public Object extractData(ResultSet rs) throws SQLException,   DataAccessException {  List<User> userList = new ArrayList<User>();  while (rs.next()) {  User user = new User();  user.setId(rs.getInt("N_ID"));  user.setName(rs.getString("C_NAME"));  userList.add(user);  }  return userList;  }  });  

2、org.springframework.jdbc.core.RowCallbackHandler

              RowCallbackHandler接口中定义的方法如下:

public interface RowCallbackHandler {  void processRow(ResultSet rs) throws SQLException;  }  

 如果使用RowCallbackHandler接口作为回调方法,查询方式如下:


final List<User> userList = new ArrayList<User>();  jdbcDao.getJdbcTemplate().query("select * from T_USER",   new RowCallbackHandler(){  @Override  public void processRow(ResultSet rs) throws SQLException {  User user = new User();  user.setId(rs.getInt("N_ID"));  user.setName(rs.getString("C_NAME"));  userList.add(user);  }  });  

3、org.springframework.jdbc.core.RowMapper

               RowMapper接口中定义的方法如下:


public interface RowMapper {  Object mapRow(ResultSet rs, int rowNum) throws SQLException;
}  

       如果使用RowMapper接口作为回调方法,查询方式如下:

List<User> userList = (List<User>)jdbcDao.getJdbcTemplate().
query("select * from T_USER", new RowMapper(){  @Override  public Object mapRow(ResultSet rs, int rowNumber)
throws SQLException {  User user = new User();  user.setId(rs.getInt("N_ID"));  user.setName(rs.getString("C_NAME"));  return user;  }  });  

通过以上的例子我们可以看出,使用三种回调接口主要的区别是:

1、使用三种Callback接口作为参数的query方法的返回值不同:

以ResultSetExtractor作为方法参数的query方法返回Object型结果,要使用查询结果,我们需要对其进行强制转型;

以RowMapper接口作为方法参数的query方法直接返回List型的结果;

以RowCallbackHandler作为方法参数的query方法,返回值为void;

2、使用ResultSetExtractor作为Callback接口处理查询结果,我们需要自己声明集合类,自己遍历    ResultSet,自己根据每行数据组装Customer对象,自己将组装后的Customer对象添加到集合类中,方法最终只负责将组装完成的集合返回。

对于这三个回调接口的区别,spring的官方文档给出的说明是这样描述的:

ResultSetExtractor

This interface is mainly used within the JDBC framework itself. A RowMapper is usually a simpler choice for ResultSet processing, mapping one result object per row instead of one result object for the entire ResultSet.
Note: In contrast to a RowCallbackHandler, a ResultSetExtractor object is typically stateless and thus reusable, as long as it doesn't access stateful resources (such as output streams when streaming LOB contents) or keep result state within the object.

RowCallbackHandler

In contrast to a ResultSetExtractor, a RowCallbackHandler object is typically stateful: It keeps the result state within the object, to be available for later inspection. SeeRowCountCallbackHandler for a usage example.
Consider using a RowMapper instead if you need to map exactly one result object per row, assembling them into a List.

RowMapper

Typically used either for JdbcTemplate's query methods or for out parameters of stored procedures. RowMapper objects are typically stateless and thus reusable; they are an ideal choice for implementing row-mapping logic in a single place.
Alternatively, consider subclassing MappingSqlQuery from the jdbc.object package: Instead of working with separate JdbcTemplate and RowMapper objects, you can build executable query objects (containing row-mapping logic) in that style.

 

通过spring的文档描述我们可以知道:

1、RowMapper应该就是一个精简版的ResultSetExtractor,RowMapper能够直接处理一条结果集内容,而ResultSetExtractor需要我们自己去ResultSet中去取结果集的内容,但是ResultSetExtractor拥有更多的控制权,在使用上可以更灵活;

2、与RowCallbackHandler相比,ResultSetExtractor是无状态的,他不能够用来处理有状态的资源。

备注:在spring3中,这三个接口的内容也做出了修改,其中:ResultSetExtractor和RowMapper开始支持泛型,返回值的内容也是泛型中的对象,而RowCallbackHandler没有做出任何修改。

转载于:https://my.oschina.net/u/2245781/blog/1579808

使用spring的JdbcTemplate进行查询的三种回调方式的比较相关推荐

  1. spring注解之@Import注解的三种使用方式

    1.@Import注解须知 1.@Import只能用在类上 ,@Import通过快速导入的方式实现把实例加入spring的IOC容器中 2.加入IOC容器的方式有很多种,@Import注解就相对很牛皮 ...

  2. Spring 依赖注入的理解及三种注入方式

    Spring 依赖注入概念和三种注入方式(理解及应用) 什么是注入 要了解Spring的三种注入方式首先前提是得先了解一下什么是注入,相信很多人对这个概念都是模糊不清的,网上的解释是这样的: 依赖注入 ...

  3. Spring Boot项目(Maven\Gradle)三种启动方式及后台运行详解

    Spring Boot项目三种启动方式及后台运行详解 1 Spring Boot项目三种启动方法 运行Application.java类中的Main方法 项目管理工具启动 Maven项目:mvn sp ...

  4. Spring的三种注入方式(为什么推荐构造器注入?)

    Spring的三种注入方式 一.属性注入 @Resource和@Autowired的区别 为什么尽量使用 @Resource? 二.setter 注入 三.构造器注入 具体可以看看Spring官网 为 ...

  5. Spring AOP的三种实现方式

    目录 一.什么是AOP 二.Spring AOP的三种实现方式 1.通过Spring API实现AOP (1)编写业务接口和实现类 (2)编写增强类,并实现Spring API相关接口的方法 (3)在 ...

  6. Spring bean 实现生命周期的三种解决方案

    Spring bean 实现生命周期的三种解决方案 参考文章: (1)Spring bean 实现生命周期的三种解决方案 (2)https://www.cnblogs.com/javawebsoa/a ...

  7. spring三种注入方式

    设置Spring的作用域 或者使用枚举值设置 单例和多里使用场景 自动注入 @Primary 一个接口有多个实现被spring管理吗,在依赖注入式,spring会不知道注入哪个实现类就会抛出NoUni ...

  8. mysql 数据查询优化_优化MySQL数据库查询的三种方法

    任何一位数据库程序员都会有这样的体会:高通信量的数据库驱动程序中,一条糟糕的SQL查询语句可对整个应用程序的运行产生严重的影响,其不仅消耗掉更多的数据库时间,且它将对其他应用组件产生影响. 如同其它学 ...

  9. MyBatis实现模糊查询的三种方式

    MyBatis实现模糊查询的三种方式 准备 模糊查询 方式一 方式二 方式三 由于#{}是占位符本身,自带单引号,所以在模糊查询时需要一些技巧. 准备 数据库表 bean 模糊查询 以查询出所有用户名 ...

  10. 如何使用计算机查询本机网卡信息,本机mac地址查询的三种方法

    现在电脑非常流行,大部分的学生以及白领或者说每一个家庭几乎都有一台电脑.不过大家对于电脑的认识却没有这么高的普及度.很多人对于它的了解仅仅停留在使用电脑看视频用软件的层面,对于电脑自身的认识不是很多. ...

最新文章

  1. R语言使用haven包的read_spss函数读取spss格式数据、使用haven包的read_sas函数读取SAS格式数据、使用haven包的read_dta函数读取Stata格式数据
  2. Python中将dict转换为kwargs
  3. Android 实现歌词变红效果
  4. Python制作植物大战僵尸小游戏
  5. 安全性问题(数据篡改(拿到别人的URL,篡改数据(金额)发送给系统))
  6. oracle怎么查询换行符,关于oracle:如何检查表中所有列的换行符
  7. 数据可视化的基本原理——视觉通道
  8. 【开发者成长】5 分钟搞定 Linux 正则表达式
  9. linux make指定目标平台,CMake on Linux:目标平台不支持动态链接
  10. 中国内鼻扩张器市场趋势报告、技术动态创新及市场预测
  11. 归并排序时间复杂度过程分析
  12. 用ILDasm.exe深入理解委托
  13. 简述 mybatis 事务的使用
  14. 多线程 VS 多进程(一)
  15. Moon Modeler v1.6.5功能和特点
  16. c 语言打印26个大写字母怎么读,26个大写字母读法
  17. Thrift交流(二)thrift服务端和客户端实现 Nifty
  18. java时间戳 时分秒_orale获取两个时间戳字符串之间的时间差(时分秒)(含java实现)...
  19. VMware虚拟机快速复制多个Linux系统
  20. 2007年9月运势之水瓶座

热门文章

  1. H.264技术及原理
  2. java argument parse_snmp4j 之 ArgumentParser
  3. python复利代码_python复利
  4. 查看谁连接oracle,oracle如何查看当前有哪些用户连接到数据库
  5. java 反射与封装性的_Java反射的封装
  6. python 指定时间内_python获取指定时间段内的随机不重复的时间点
  7. 教育计算机缩写,{教育管理}计算机缩写术语完全介绍宝典.docx
  8. python 图片 变清晰_python模糊图片过滤的方法
  9. python面试必备10题_不吹不擂,你想要的Python面试都在这里了【315+道题】+精心整理的解答...
  10. python做一个本地搜索_用 python, django 实现的一个很简单的搜索引擎