`
liangfeng366
  • 浏览: 78075 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
社区版块
存档分类
最新评论

JdbcTemplate查询数据 三种callback之间的区别

阅读更多
JdbcTemplate针对数据查询提供了多个重载的模板方法,你可以根据需要选用不同的模板方法。 如果你的查询很简单,仅仅是传入相应SQL或者相关参数,然后取得一个单一的结果,那么你可以选择如下一组便利的模板方法:

int queryForInt(String sql)

int queryForInt(String sql, Object[] args)

long queryForLong(String sql)

long queryForLong(String sql, Object[] args)

Object queryForObject(String sql, Class requiredType)

Object queryForObject(String sql, Object[] args, Class requiredType)

Map queryForMap(String sql)

Map queryForMap(String sql, Object[] args)

比如说,你所查询的结果就包含一列数字型的结果,或者使用了SQL函数,或者其他单列的结果,我们就可以直接通过这组便利的模板方法进行查询:
int age = jdbcTemplate.queryForInt("select age from customer where customerId=?",new Object[]{new Integer(100)});
...
long interval = jdbcTemplate.queryForLong("select count(customerId) from customer");
...
String customerName = jdbcTemplate.queryForString("select username from customer where customerId=110");
...
Map singleCustomer = jdbcTemplate.queryForMap("select * from customer limit 1");
...
queryForMap方法与其他方法不同之处在于,它的查询结果以java.util.Map的形式返回,Map的key对应所查询表的列名,Map的value当然就是对应key所在列的值啦。 当然了,你也看到了,这组模板方法主要用于单一结果的查询,使用的时候也请确保你的SQL查询所返回的结果是单一的,否则,JdbcTemplate将抛出org.springframework.dao.IncorrectResultSizeDataAccessException异常。
如果查询的结果将返回多行,而你又不在乎他们是否拥有较强的类型约束,那么,以下模板方法可以帮助你:

List queryForList(String sql)

List queryForList(String sql, Object[] args)

queryForList方法根据传入的SQL以及相应的参数执行查询,将查询的结果以java.util.List的形式返回,返回的java.util.List中的每一个元素都是java.util.Map类型,分别对应结果集中的一行,Map的Key为每一列的列名,而Map的值就是当前行列名对应的值。
好啦,如果这些还不足以满足你的查询需要,那么我们就更进一步,使用相应的Callback接口对查询结果的返回进行定制吧!

用于查询的回调接口定义主要有以下三种:

org.springframework.jdbc.core.ResultSetExtractor.  基本上属于JdbcTemplate内部使用的Callback接口,相对于下面两个Callback接口来说,ResultSetExtractor拥有更多的控制权,因为使用它,你需要自行处理ResultSet:

public interface ResultSetExtractor
{
Object extractData(ResultSet rs) throws SQLException, DataAccessException;
}
在直接处理完ResultSet之后,你可以将处理后的结果以任何你想要的形式包装后返回。
org.springframework.jdbc.core.RowCallbackHandler.  RowCallbackHandler相对于ResultSetExtractor来说,仅仅关注单行结果的处理,处理后的结果可以根据需要存放到当前RowCallbackHandler对象内或者使用JdbcTemplate的程序上下文中,当然,这个完全是看个人爱好了。 RowCallbackHandler的定义如下:

public interface RowCallbackHandler
{
void processRow(ResultSet rs) throws SQLException;
}
org.springframework.jdbc.core.RowMapper.  ResultSetExtractor的精简版,功能类似于RowCallbackHandler,也只关注处理单行的结果,不过,处理后的结果会由ResultSetExtractor实现类进行组合。 RowMapper的接口定义如下:

public interface RowMapper
{
Object mapRow(ResultSet rs, int rowNum) throws SQLException;
}
为了说明这三种Callback接口的使用和相互之间的区别,我们暂且设定如下场景:
数据库表customer中存在多行信息,对该表查询后,我们需要将每一行的顾客信息都映射到域对象Customer中,并以java.util.List的形式返回所有的查询结果。

现在,我们分别使用这三种Callback接口对customer表进行查询:

List customerList = (List)jdbcTemplate.query("select * from customer", new ResultSetExtractor(){

public Object extractData(ResultSet rs) throws SQLException,DataAccessException
{
List customers = new ArrayList();
while(rs.next())
{
Customer customer = new Customer();
customer.setFirstName(rs.getString(1));
customer.setLastName(rs.getString(2));
...
customers.add(customer);
}
return customers;
}});
List customerList = jdbcTemplate.query("select * from customer", new RowMapper(){

public Object mapRow(ResultSet rs, int rowNumber) throws SQLException {
Customer customer = new Customer();
customer.setFirstName(rs.getString(1));
customer.setLastName(rs.getString(2));
...
return customer;
}});
final List customerList = new ArrayList();

jdbcTemplate.query("select * from customer", new RowCallbackHandler(){

public void processRow(ResultSet rs) throws SQLException {
Customer customer = new Customer();
customer.setFirstName(rs.getString(1));
customer.setLastName(rs.getString(2));
...
customerList.add(customer);
}});
如果你没有发现最大的差异在哪里,那么容我细表:
使用三种Callback接口作为参数的query方法的返回值不同:

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

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

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

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

使用RowMapper比直接使用ResultSetExtractor要方便的多,只负责处理单行结果就行,现在,我们只需要将单行的结果组装后返回就行,剩下的工作,全部都是JdbcTemplate内部的事情了。 实际上,JdbcTemplae内部会使用一个ResultSetExtractor实现类来做其余的工作,毕竟,该做的工作还得有人做不是?!

JdbcTemplae内部使用的这个ResultSetExtractor实现类为org.springframework.jdbc.core.RowMapperResultSetExtractor, 它内部持有一个RowMapper实例的引用,当处理结果集的时候,会将单行数据的处理委派给其所持有的RowMapper实例,而其余工作它负责:

public Object extractData(ResultSet rs) throws SQLException {
List results = (this.rowsExpected > 0 ? new ArrayList(this.rowsExpected) : new ArrayList());
int rowNum = 0;
while (rs.next()) {
results.add(this.rowMapper.mapRow(rs, rowNum++));
}
return results;
}
这下应该清楚为啥RowMapper为啥就处理单行结果就能完成ResultSetExtractor颇费周折的工作了吧?!
RowCallbackHandler虽然与RowMapper同是处理单行数据,不过,除了要处理单行结果,它还得负责最终结果的组装和获取工作,在这里我们是使用当前上下文声明的List取得最终查询结果, 不过,我们也可以单独声明一个RowCallbackHandler实现类,在其中声明相应的集合类,这样,我们可以通过该RowCallbackHandler实现类取得最终查询结果:

public class GenericRowCallbackHandler implements RowCallbackHandler {
private List collections = new ArrayList();

public void processRow(ResultSet rs) throws SQLException {
Customer customer = new Customer();
customer.setFirstName(rs.getString(1));
customer.setLastName(rs.getString(2));
...
collections.add(customer);
}

public List getResults()
{
return collections;
}
}

GenericRowCallbackHandler handler = new GenericRowCallbackHandler();
jdbcTemplate.query("select * from customer",handler());
List customerList = handler.getResults();
该使用方式是明了了,不过GenericRowCallbackHandler重用性不佳。
RowCallbackHandler因为也是处理单行数据,所以,总得有人来做遍历ResultSet的工作,这个人其实也是一个ResultSetExtractor实现类, 它是JdbcTemplate一个内部静态类,名为RowCallbackHandlerResultSetExtractor,一看它的定义你就知道奥秘之所在了:

private static class RowCallbackHandlerResultSetExtractor implements ResultSetExtractor {

private final RowCallbackHandler rch;

public RowCallbackHandlerResultSetExtractor(RowCallbackHandler rch) {
this.rch = rch;
}

public Object extractData(ResultSet rs) throws SQLException {
while (rs.next()) {
this.rch.processRow(rs);
}
return null;
}
}
总的来说,内部工作归根结底是由ResultSetExtractor做了,RowCallbackHandler和RowMapper只是为了帮助我们简化使用上的操作而已。 所以,实际使用中,RowCallbackHandler和RowMapper才是我们最常用的选择。
对于使用JdbcTemplate进行查询,基本就这些内容了,当然,如果你非要使用基于StatementCallback之类更底层的execute方法的话,那就是你个人说了算啦。 不过,要想知道JdbcTemplate中有关查询相关模板方法的更多信息,在实际使用中参考JdbcTemplate的javadoc就可以,当然,有IDE就更便捷了。



本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/congqian1120/archive/2008/01/16/2046311.aspx
分享到:
评论
1 楼 107x 2014-04-29  
不错,谢谢分享

相关推荐

    JdbcTemplate查询

    ### JdbcTemplate查询详解 #### 一、概述 `JdbcTemplate`是Spring框架中提供的一个用于简化JDBC编程的工具类,它提供了丰富的API来帮助开发者更便捷地进行数据库操作。相较于传统的JDBC编程方式,使用`...

    java spring手写jdbcTemplate,实现查询多数据源数据。

    最近项目中的工作流需要查询多个数据源的数据,数据源可能是不同种类的:如sql server,oracl等等,一开始是用的配置实现,后来发现在项目运行中,可能需要动态的添加更多不同类型的数据源,所以最终的逻辑是将数据源...

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

    除了基本的查询和更新,`jdbcTemplate`还支持回调(Callback)机制,允许我们在执行数据库操作的过程中进行额外的处理。例如,我们可以使用`SimpleJdbcCall`来执行存储过程,并提供一个`SqlParameterSource`来传递...

    SpringBoot操作多数据源(JPA+JdbcTemplate)

    3. **JdbcTemplate**: Spring提供的一个用于简化数据库操作的模板类,它提供了一套方便的API,可以用于执行SQL查询和更新,无需手动管理数据库连接。 4. **HikariCP**: 这是一个高性能的Java数据库连接池,它的设计...

    SpringBoot+JPA+JTA(可选)+JdbcTemplate多数据源配置源码

    本资源包含了两个子项目,分别进行了springboot+jpa+jdbcTemplate的多数据源独立事务配置和jta分布式事务配置,并针对不同的情况编写了事务配置测试接口,还演示了JPA的domain一对多自动生成数据库表且不生成数据库...

    jdbcTemplate分页彻底解决,使用游标滚动

    总结来说,`JdbcTemplate`配合游标滚动是一种有效的分页解决方案,尤其是在处理大数据量时。通过自定义`ResultSetExtractor`,我们可以灵活控制分页逻辑,降低内存消耗,提升系统性能。通过阅读和理解`...

    Spring JdbcTemplate查询实例

    Spring JdbcTemplate是Spring框架中用于简化数据库操作的一个重要组件,它是Spring对JDBC的轻量级封装,旨在提供一种结构良好、易于使用的SQL执行机制,同时保持了JDBC的灵活性。在本实例中,我们将深入探讨Spring ...

    jdbctemplatedemo.zip

    Spring Boot简化了Java应用程序的开发,而JdbcTemplate作为Spring框架的一部分,提供了一种方便、安全的方式来访问关系型数据库,避免了直接编写SQL和手动处理结果集的繁琐工作。 首先,让我们了解Spring Boot。它...

    Spring Boot多数据源(JdbcTemplate)配置与使用

    在Spring Boot应用中,我们经常需要处理来自多个数据源的数据,比如在开发微服务架构时,每个服务可能对应一个特定的数据源。`JdbcTemplate`是Spring框架提供的一个用于简化数据库操作的工具,它使得数据库访问更为...

    使用Spring的JdbcTemplate实现分页功能

    使用Spring的JdbcTemplate实现分页功能

    java基于jdbctemplate数据持久层操作封装

    Java中的JdbcTemplate是Spring框架提供的一种用于简化JDBC(Java Database Connectivity)操作的工具,它在数据持久层操作中扮演着重要角色。JdbcTemplate通过消除大量重复的JDBC样板代码,提高了代码的可读性和可...

    打印JdbcTemplate执行sql

    通过使用模板方法设计模式,`JdbcTemplate`提供了一系列静态和非静态的方法来执行各种SQL操作,如查询、更新、插入和删除。 为了打印`JdbcTemplate`执行的SQL语句,我们需要关注以下几点: 1. **日志配置**:首先...

    Spring框架JdbcTemplate类中查询方法介绍

    Spring 框架 JdbcTemplate 类中查询方法介绍 JdbcTemplate 是 Spring 框架中 org.springframework.jdbc.core 包提供的 JDBC 模板类,它是核心类,其他模板类都是基于它封装完成的。JdbcTemplate 类主要提供四类方法...

    使用jdbcTemplate查询返回自定义对象集合代码示例

    其中,使用JdbcTemplate查询返回自定义对象集合是非常常见的一种操作。今天,我们将探讨使用JdbcTemplate查询返回自定义对象集合的代码示例。 一、使用JdbcTemplate.queryForList()方法 首先,我们可以使用...

    Jdbctemplate多数据源配置方法详解

    Jdbctemplate 多数据源配置方法详解 Jdbctemplate 多数据源配置是指在 Spring Boot 应用程序中配置多个数据源,以便在不同的业务场景下使用不同的数据库。下面将详细介绍 Jdbctemplate 多数据源配置方法。 数据源...

    spring mvc配置 + dbcp数据源+jdbcTemplate

    JdbcTemplate是Spring框架的一部分,它提供了一种简化Java数据库编程的方法。通过使用JdbcTemplate,开发者可以避免编写大量重复的JDBC模板代码,例如打开和关闭连接、处理结果集等,从而更专注于业务逻辑。 首先,...

    SpringJdbcTemplate封装工具类

    这个封装工具类的出现是为了提供一种更简洁、易于使用的接口来执行SQL操作,减轻开发者处理数据库连接、事务管理以及异常处理的负担。下面我们将深入探讨SpringJdbcTemplate的相关知识点。 1. **SpringJdbcTemplate...

    jdbcTemplate

    `JdbcTemplate`是Spring框架中的一个核心组件,主要用于简化Java应用程序与关系数据库之间的交互。它提供了模板化的SQL执行方法,从而避免了繁琐的JDBC代码编写,提高了代码的可读性和可维护性。项目经理编写的这个`...

    Spring jdbctemplate + mysql 分页封装

    本文将深入探讨如何利用Spring的JdbcTemplate进行MySQL数据库的分页查询,并对其进行封装,提高代码的复用性和可维护性。 首先,了解Spring JdbcTemplate的基本用法。JdbcTemplate是Spring提供的一个模板类,用于...

Global site tag (gtag.js) - Google Analytics