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

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

 

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


 

可是这三种回调接口具体的用法和区别,咱们一块儿来看一下:app

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

       一、org.springframework.jdbc.core.ResultSetExtractoride

     ResultSetExtractor接口中定义的方法以下:学习

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

    若是使用ResultSetExtractor接口做为回调方法,查询方式以下:ui

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;  
            }  
    });

        二、org.springframework.jdbc.core.RowCallbackHandleridea

              RowCallbackHandler接口中定义的方法以下:code

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);  
       }  
   });

         三、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;  
            }  
      });

          经过以上的例子咱们能够看出,使用三种回调接口主要的区别是:

         一、使用三种Callback接口做为参数的query方法的返回值不一样:

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

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

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

         二、使用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的文档描述咱们能够知道:

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

二、与RowCallbackHandler相比,ResultSetExtractor是无状态的,他不可以用来处理有状态的资源。

 

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

相关文章
相关标签/搜索