本文浅析 spring jdbcTemplate 源码,主要是学习其设计精髓。模板模式、巧妙的回调

一、jdbcTemplate 类结构

①、JdbcOperations : 接口定义了方法,如

<T> T execute(StatementCallback<T> action) throws DataAccessException;

void execute(String sql) throws DataAccessException;

<T> T query(String sql, ResultSetExtractor<T> rse) throws DataAccessException;

。。。

②、JdbcAccessor : 定义了数据源。

③、实现JdbcOperations接口定义的方法

二、jdbcTemplate 模板模式

1、我们看下execute(StatementCallback<T> action)实现 (核心)

  1. public <T> T execute(StatementCallback<T> action) throws DataAccessException {
  2. Assert.notNull(action, "Callback object must not be null");
  3.  
  4. Connection con = DataSourceUtils.getConnection(getDataSource());
  5. Statement stmt = null;
  6. try {
  7. Connection conToUse = con;
  8. if (this.nativeJdbcExtractor != null &&
  9. this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
  10. conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
  11. }
  12. stmt = conToUse.createStatement();
  13. applyStatementSettings(stmt);
  14. Statement stmtToUse = stmt;
  15. if (this.nativeJdbcExtractor != null) {
  16. stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
  17. }
  18. T result = action.doInStatement(stmtToUse); // 回调
  19. handleWarnings(stmt);
  20. return result;
  21. }
  22. catch (SQLException ex) {
  23. JdbcUtils.closeStatement(stmt);
  24. stmt = null;
  25. DataSourceUtils.releaseConnection(con, getDataSource());
  26. con = null;
  27. throw getExceptionTranslator().translate("StatementCallback", getSql(action), ex);
  28. }
  29. finally {
  30. JdbcUtils.closeStatement(stmt);
  31. DataSourceUtils.releaseConnection(con, getDataSource());
  32. }
  33. }

2、再看下 execute(String sql) 源码

  1. public void execute(final String sql) throws DataAccessException {
  2. if (logger.isDebugEnabled()) {
  3. logger.debug("Executing SQL statement [" + sql + "]");
  4. }
  5. class ExecuteStatementCallback implements StatementCallback<Object>, SqlProvider {
  6. @Override
  7. public Object doInStatement(Statement stmt) throws SQLException {
  8. stmt.execute(sql); // JAVA jdbc
  9. return null;
  10. }
  11. @Override
  12. public String getSql() {
  13. return sql;
  14. }
  15. }
  16. execute(new ExecuteStatementCallback()); // 调用上述T execute(StatementCallback<T> action) 
  17. }

由此,可以知道,我们平时常用的execute(final String sql) 方法,底层帮我们做了很多事情,如创建默认的ExecuteStatementCallback,采用回调的方式,由模板去执行sql,关闭链接

3、T query(final String sql, final ResultSetExtractor<T> rse) 源码实现

  1. @Override
  2. public <T> T query(final String sql, final ResultSetExtractor<T> rse) throws DataAccessException {
  3. Assert.notNull(sql, "SQL must not be null");
  4. Assert.notNull(rse, "ResultSetExtractor must not be null");
  5. if (logger.isDebugEnabled()) {
  6. logger.debug("Executing SQL query [" + sql + "]");
  7. }
  8. class QueryStatementCallback implements StatementCallback<T>, SqlProvider {
  9. @Override
  10. public T doInStatement(Statement stmt) throws SQLException {
  11. ResultSet rs = null;
  12. try {
  13. rs = stmt.executeQuery(sql);
  14. ResultSet rsToUse = rs;
  15. if (nativeJdbcExtractor != null) {
  16. rsToUse = nativeJdbcExtractor.getNativeResultSet(rs);
  17. }
  18. return rse.extractData(rsToUse);
  19. }
  20. finally {
  21. JdbcUtils.closeResultSet(rs);
  22. }
  23. }
  24. @Override
  25. public String getSql() {
  26. return sql;
  27. }
  28. }
  29. return execute(new QueryStatementCallback());
  30. }

4、update(final String sql) 源码

  1. @Override
  2. public int update(final String sql) throws DataAccessException {
  3. Assert.notNull(sql, "SQL must not be null");
  4. if (logger.isDebugEnabled()) {
  5. logger.debug("Executing SQL update [" + sql + "]");
  6. }
  7. class UpdateStatementCallback implements StatementCallback<Integer>, SqlProvider {
  8. @Override
  9. public Integer doInStatement(Statement stmt) throws SQLException {
  10. int rows = stmt.executeUpdate(sql);
  11. if (logger.isDebugEnabled()) {
  12. logger.debug("SQL update affected " + rows + " rows");
  13. }
  14. return rows;
  15. }
  16. @Override
  17. public String getSql() {
  18. return sql;
  19. }
  20. }
  21. return execute(new UpdateStatementCallback());
  22. }

spring jdbcTemplate源码剖析的更多相关文章

  1. Spring JdbcTemplate源码阅读报告

    写在前面 spring一直以删繁就简为主旨,所以设计出非常流行的bean管理模式,简化了开发中的Bean的管理,少写了很多重复代码.而JdbcTemplate的设计更令人赞叹,轻量级,可做ORM也可如 ...

  2. spring jdbctemplate源码跟踪

    闲着没事,看看源码也是一种乐趣! java操作数据库的基本步骤都是类似的: 1. 建立数据库连接 2. 创建Connection 3. 创建statement或者preparedStateement ...

  3. Spring缓存源码剖析:(一)工具选择

    从本篇开始对Spring 4.3.6版本中Cache部分做一次深度剖析.剖析过程中会对其中使用到的设计模式以及原则进行分析.相信对设计内功修炼必定大有好处. 一.环境及工具 IntelliJ IDEA ...

  4. Spring源码剖析9:Spring事务源码剖析

    转自:http://www.linkedkeeper.com/detail/blog.action?bid=1045 声明式事务使用 Spring事务是我们日常工作中经常使用的一项技术,Spring提 ...

  5. Spring缓存源码剖析:(二)CacheManager

    一.CacheManager总览 如果需要Spring缓存可以正常工作,必须配置一个CacheManager. CacheManager实现类你可以配置Spring-context本身提供的Simpl ...

  6. Spring源码剖析依赖注入实现

    Spring源码剖析——依赖注入实现原理 2016年08月06日 09:35:00 阅读数:31760 标签: spring源码bean依赖注入 更多 个人分类: Java   版权声明:本文为博主原 ...

  7. 转 Spring源码剖析——核心IOC容器原理

    Spring源码剖析——核心IOC容器原理 2016年08月05日 15:06:16 阅读数:8312 标签: spring源码ioc编程bean 更多 个人分类: Java https://blog ...

  8. Spring事务源码分析专题(一)JdbcTemplate使用及源码分析

    Spring中的数据访问,JdbcTemplate使用及源码分析 前言 本系列文章为事务专栏分析文章,整个事务分析专题将按下面这张图完成 对源码分析前,我希望先介绍一下Spring中数据访问的相关内容 ...

  9. Spring 源码剖析IOC容器(一)概览

    目录 一.容器概述 二.核心类源码解读 三.模拟容器获取Bean ======================= 一.容器概述 spring IOC控制反转,又称为DI依赖注入:大体是先初始化bean ...

随机推荐

  1. 捉虫记2:windows程序句柄泄露的上下文环境

    作为程序员,开发程序是基本功,而调试程序也是必不可少的技能之一.软件在主体功能开发完成后会经历各个阶段的测试,才会被发布.在测试过程中,出现较多的可能就是内存泄漏,句柄泄漏,异常崩溃等属于非功能型的软 ...

  2. 各种好用的工具之一 ---- PNGGauntlet

    1.PNGGauntlet实际上是一个图形前端,压缩图像的过程中使用的是PNGOUT, OptiPNG, 和DeflOpt这三款软件. 软件官网:http://pnggauntlet.com/ 可自行 ...

  3. PASCALmath库

    noi上是让用,noip让用么?貌似不让— — 反正是好东西.在FP中,Math库为我们提供了丰富的数学函数.以下介绍在OI中可能会用到的Math库中一些函数.过程. 使用方法:在程序头用Uses语句 ...

  4. HHVM 是如何提升 PHP 性能的?

    背景 HHVM 是 Facebook 开发的高性能 PHP 虚拟机,宣称比官方的快9倍,我很好奇,于是抽空简单了解了一下,并整理出这篇文章,希望能回答清楚两方面的问题: HHVM 到底靠谱么?是否可以 ...

  5. (转)innodb 与 myisam 读写性能分析

    前提: mysql在5.0之前,读写性能相差很大,读性能:myisam 很强 mysql在5.0之后,差距不是很大 http://passover.blog.51cto.com/2431658/507 ...

  6. JDBC基础教程

    本文实例讲述了JDBC基础知识与技巧.分享给大家供大家参考.具体分析如下: 1.什么是JDBC? 通俗来讲JDBC技术就是通过java程序来发送SQL语句到数据库,数据库收到SQL语句后执行,把结果返 ...

  7. http://www.cnblogs.com/youfan/articles/3216816.html

    我对 CodeFirst 的理解,与之对应的有 ModelFirst与 DatabaseFirst ,三者各有千秋,依项目实际情况自行选择. 1.开发过程中先行设计数据库并依此在项目中生成 *.dbm ...

  8. javascript-实现日期大写

    <script language="javascript"> $(document).ready(function() { //定义中文数组 var chinese = ...

  9. 问题:关于贴友一个用js传递value默认值的简单实现

    需求和代码如下: “这是我的代码:” 1: <input type="text" id="price2" value="333"/&g ...

  10. Magento 前台的logo更改

    进入后台: 系统-配置, 然后选择左栏的“设计”, 选择右栏的“页眉”里面, 一般logo的路径在: skin/frontend/base/default/images/media/logo.png ...