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表进行查询:

//org.springframework.jdbc.core.ResultSetExtractor
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); //list add etim} return customers; //return list}
}); //org.springframework.jdbc.core.RowMapper.
List customerList = jdbcTemplate.query("select * from customer", new RowMapper(){public Object mapRow(ResultSet rs, int rowNumber) throws SQLException { //rowNumber 什么时候用到?Customer customer = new Customer(); customer.setFirstName(rs.getString(1));customer.setLastName(rs.getString(2)); //... return customer; //return single object}
}); //org.springframework.jdbc.core.RowCallbackHandler
final List customerList = new ArrayList(); //final List,匿名内部类只能用不可变的外部局部变量
jdbcTemplate.query("select * from customer", new RowCallbackHandler(){ public void processRow(ResultSet rs) throws SQLException { //return voidCustomer customer = new Customer(); customer.setFirstName(rs.getString(1));customer.setLastName(rs.getString(2)); //... customerList.add(customer); //add the result into the list,}
});

如果你没有发现最大的差异在哪里,那么容我细表: 
使用三种Callback接口作为参数的query方法的返回值不同:

以ResultSetExtractor作为方法参数的query方法返回Object型结果,要使用查询结果,我们需要对其进行强制转型; 
//该object是一个list,为什么不直接返回list? 之所以不做过多的限制就是为了让别的方法在它的基础上更方便的集成,也能给开发者带来更大的灵活性

以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++)); //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






















												

JdbcTemplate 简介相关推荐

  1. jdbcTemplate数据库连接的使用

    JdbcTemplate简介 Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中. JdbcTempla ...

  2. SpringBoot2.0 基础案例(06):引入JdbcTemplate,和多数据源配置

    一.JdbcTemplate对象 1.JdbcTemplate简介 在Spring Boot2.0框架下配置数据源和通过JdbcTemplate访问数据库的案例. SpringBoot对数据库的操作在 ...

  3. jdbc与jdbctemplate区别

    什么是JDBC? ①JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API, 可以为多种关系数据库提供统一访问,它由一组用Jav ...

  4. Spring JdbcTemplate + transactionTemplate 简单示例 (零配置)

    jdbcTemplate简介 Spring对数据库的操作在jdbc上面做了深层次的封装,使用spring的注入功能,可以把DataSource注册到JdbcTemplate之中. JdbcTempla ...

  5. SpringBoot整合JDBC、整合Druid数据源详解教程

    目录 一.整合JDBC 1. 环境准备 1. 创建数据库 2. 创建SpringBoot项目 3. IDEA连接数据库 2. 编写数据库配置信息 3. 编写测试类测试 4. CRUD操作数据库 1. ...

  6. SpringBoot2 综合案例(05):定时任务和JDBC多数据源配置

    Spring Boot 2 基础案例篇 包含:入门.日志管理.定时器.事务.AOP.数据库.缓存.NoSQL.监控.打包. Spring Boot 2 高级案例篇 包含:整合常用中间件:分库分表.权限 ...

  7. spring史上最全笔记

    Spring笔记 目录 概念: 优点 IOC 控制反转 控制什么? 谁来控制? 反转? 依赖注入DI? IOC和DI关系 IOC本质 ★获取IOC容器 ★bean的三种创建实例的方式 FactoryB ...

  8. 超全面Java全栈知识体系,定期更新(最近更新:2022.8.2)...

    前言 最新Java全栈知识系统,定期更新..... 本套知识体系涵盖六大块: 一.前端基础 涵盖HTML5.CSS3.JavaScript.jQuery.Layui.Bootstrap等: 二.Jav ...

  9. Java最强最新知识体系总结(2021版)

    一.Java基础知识 1.基础知识 分类 内容 链接 Java基础 [Java知识点详解 1]缓存 链接1 Java基础 [Java知识点详解 2]动态代理 链接2 Java基础 [Java知识点详解 ...

最新文章

  1. php window.onload,window.onload 触发时机问题
  2. javaweb成长之路:struts2的探索(一)
  3. 【模板篇】数论大杂烩~
  4. maya刷权重时有个叉_运营小白如何注册一个高权重的抖音账号?
  5. Spring boot yml文件的书写格式
  6. python基础语法、数据结构、字符编码、文件处理 练习题
  7. 频谱仪的更改ip_通过局域网(LAN)读取频谱分析仪图像的方法
  8. java初级程序员需要掌握哪些,附源代码
  9. 已知圆的半径radius= 1.5,求其面积
  10. 华为手机的10个使用技巧,你知道吗
  11. vue回到顶部(常用)
  12. 视频管理系统源码php,video cms 视频分享管理系统
  13. 【场景削减】拉丁超立方抽样方法场景削减(Matlab代码实现)
  14. btcTrade_project
  15. 详细解读《个人所得税专项附加扣除暂行办法》
  16. [Brute force][规律] Jzoj P3084 超级变变变
  17. pikachu RCE(remote command/code execute)(远程命令执行/远程代码执行)(皮卡丘漏洞平台通关系列)
  18. 记一次 解决 Xshell 连接 Linux 系统,使用数字小键盘乱码问题
  19. 51单片机:外部中断实现流水灯
  20. 如何使用 jQuery 异步上传文件?

热门文章

  1. 为什么那么多人选择承制的CISP-PTE培训?
  2. worksheets 和 sheets 的不同
  3. MySQL 8.0 参考手册
  4. 等价类划分经典实例-三角形测试用例设计
  5. 在Elasticsearch中回测阿隆(Aroon)指標交叉交易策略
  6. Ubuntu 22.04 安装R语言及R studio
  7. 人机大战?——带你玩转三子棋(C语言)
  8. 使用Beaglebone Black的PRU(二)——Hello World!
  9. HTTP协议的请求格式解析
  10. BigDecimal的使用