`
董宗磊
  • 浏览: 64339 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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

 
阅读更多

我们做过的很多项目中都会使用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没有做出任何修改。

  • 大小: 62.3 KB
分享到:
评论

相关推荐

    Spring 学习 JdbcTemplate,模板模式,回调

    NULL 博文链接:https://gutou9.iteye.com/blog/286812

    spring自带的jdbcTemplate查询、插入预编译使用

    简单的jdbcTemplate预编译、回调等

    Spring JdbcTemplate方法详解

    JdbcTemplate主要提供以下五类方法;JdbcTemplate类支持的回调类;并附例子

    JdbcTemplate教程

    除了大量使用Template Method来封装一些底层的操作细节,spring也大量使用callback方式类回调相关类别的方法以提供JDBC相关类别的功能,使传统的JDBC的使用者也能清楚了解spring所提供的相关封装类别方法的使用。

    Spring中文帮助文档

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用...

    rest风格+jdbctemplate的CRUD操作.rar

    ①查询所有员工列表:jdbcTemplate.query(sql, new RowMapper() {}回调函数的使用 ②添加员工:添加员工之前要先查询出所有部门,因此要先查询所有的部门列表,然后用POST请求添加员工,重定向回员工列表 ③删除员工...

    JdbcTemplate完全学习

    JdbcTemplate类对可变部分采用回调接口方式实现,如ConnectionCallback通过回调接口返回给用户一个连接,从而可以使用该连接做任何事情、StatementCallback通过回调接口返回给用户一个Statement,从而可以使用该...

    Spring-Reference_zh_CN(Spring中文参考手册)

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用服务器...

    Spring 2.0 开发参考手册

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用...

    Spring.3.x企业应用开发实战(完整版).part2

    8.3.1 使用模板和回调机制 8.3.2 Spring为不同持久化技术所提供的模板类 8.4 数据源 8.4.1 配置一个数据源 8.4.2 获取JNDI数据源 8.4.3 Spring的数据源实现类 8.5 小结 第9章 Spring的事务管理 9.1 数据库事务基础...

    Spring API

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用...

    spring chm文档

    12.2.4. 不使用回调的基于Spring的DAO实现 12.2.5. 基于Hibernate3的原生API实现DAO 12.2.6. 编程式的事务划分 12.2.7. 声明式的事务划分 12.2.8. 事务管理策略 12.2.9. 容器资源 vs 本地资源 12.2.10. 在应用...

    Spring3.x企业应用开发实战(完整版) part1

    8.3.1 使用模板和回调机制 8.3.2 Spring为不同持久化技术所提供的模板类 8.4 数据源 8.4.1 配置一个数据源 8.4.2 获取JNDI数据源 8.4.3 Spring的数据源实现类 8.5 小结 第9章 Spring的事务管理 9.1 数据库事务基础...

Global site tag (gtag.js) - Google Analytics