Spring源码阅读:SpringJDBC组件的设计及实现

合集下载
相关主题
  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

昨天回忆了我在学习JDBC时自己设计的JDBCTemplate(写在上一篇博客中),在使用Spring过程中,有时会用到Spring 给我们提供的JdbcTemplate,这里看看Spring是如何实现这个组件的。

在使用Spring JDBC是你要做的工作很少:
从上面的图上可以看出来,使用Spring JDBC,你只需要做四个工作:
1)定义连接参数:也就是定义url,driver,user,password这个几个参数,一般我们会用一个jdbc.properties文件来配置。

2)指定要执行那个sql语句:项目中要用到什么样的SQL语句,Spring是肯定不知道的,只能我们自己设置的。

3)使用PreparedStatement时需要参数,传递哪些参数肯定也是需要我们自己设置的。

4)迭代结果集的过程需要做那些事情,肯定也是需要我们自己写的。

之前我定义的需要做的工作有:
1)配置连接参数
2)指定sql语句
3)传递参数
4)处理结果集
综合来看,两者功能是类似的,但是我定义的那个处理能力是有限,例如处理存储过程的方式并没有一个特定的模板。

而在Spring中定义的,是一个可用性很好的组件。

根据名称就知道它也是使用了模板方法模式,那么它是如何实现的呢?又提供了哪些模板呢?
如何使用JdbcTemplate
先来复习一下,如何使用Spring JDBC组件。

在Dao层是这样使用JdbcTemplate的:
@Repository
public class JdbcCorporateEventDao implements CorporateEventDao { private JdbcTemplate jdbcTemplate;
@Autowired
public void setDataSource(DataSource dataSource) {
this.jdbcTemplate = new JdbcTemplate(dataSource);
}
// JDBC-backed implementations of the methods on the CorporateEventDao follow...
}
与上面的使用关联的Spring Bean Definition是:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="/schema/beans"
xmlns:xsi="/2001/XMLSchema-instance"
xmlns:context="/schema/context"
xsi:schemaLocation="
/schema/beans
/schema/beans/spring-beans-3.0.xsd
/schema/context
/schema/context/spring-context-3.0.xsd" >
<!-- Scans within the base package of the application for @Components to configure as beans -->
<context:component-scan
base-package="org.springframework.docs.test"/>
<bean id="dataSource"
class="mons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName"
value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${ername}"/>
<property name="password" value="${jdbc.password}"/> </bean>
<context:property-placeholder location="jdbc.properties"/>
</beans>
在Java代码中只需要指定相应的DataSource,就可以获取到JdbcTemplate对象了。

JdbcTemplate说明
JdbcTemplate作为Spring JDBC组件的核心类,很有必要来看看它是如何实现的。

View Code
1)这个类是Spring JDBC core包的主要类。

通过上面的说明,可以对JdbcTemplate有个初步的了解:
2)这个类简化了JDBC的使用,有利于避免一些常见的错误。

3)它能够执行JDBC的流程,并且能够将SQL的提供和结果的处理分离。

(其实就是说由用户来提供SQL语句,和结果处理)
4)它能够执行SQL的executeQuery,executeUpdate (这两个是Statement、PreparedStatement的方法),能够初始化ResultSet的迭代器。

5)能够帮助我们捕获异常
6)使用这个类编码时,只需要实现相应的callback接口就行了。

常用的接口有:PreparedStatementCreator、ResultSetExtractor、PreparedStatementSetter、RowMapper
7)可以通过在appliction contex中配置DataSource来直接获取JdbcTemplate对象。

8)如果想要使用log4j等来记录日志信息,需要设置:
.springframework.jdbc.core.JdbcTempl ate=debug
JdbcTemplate的结构
通过上面的类图,就可以了解到:
1)JdbcTemplate通过继承JdbcAccessor,可以从Spring IOC中获取到DataSource.
DataSource是用户在Bean定义文件中配置的。

2)JdbcOperations为JdbcTemplate提供了一些标准的操作接口。

接口中的方法都为用户操作数据库提供了极大的便利。

3)JdbcTemplate使用NativeJdbcExtractor用于从各种不同的JDBC厂商或者数据库连接池获取Connection、Statem、ResultSet等,这个类在JdbcTemplate提供的模板方法内部使用。

JdbcTemplate提供的模板
通过对JdbcTemplate提供的那些方便的方法的浏览,发现了这些方法共同特点是都是用来execute方法。

再查看execute 方法,发现了JdbcTemplate根据JDBC中的Statement的分类,提供了三种execute:
Statement语句模板:
public <T> T execute(StatementCallback<T> action)
CallableStatement语句模板:
public <T> T execute(CallableStatementCreator csc, CallableStatementCallback<T> action)
PreparedStatement语句模板:
public <T> T execute(PreparedStatementCreator psc, PreparedStatementCallback<T> action)
// 附加一种,这种很少用到
public <T> T execute(ConnectionCallback<T> action)
根据这几个模板就可以看出来,它也是采用了使用Callback的TemplateMethod模式。

接下来,分别了解他们是如何实现的:
Statement语句模板
View Code
看来这三步的操作要在StatementCallback中来完成了。

这个模板方法中对使用JDBC的流程都走了一遍。

连接的获取、打开、关闭、方法的调用、异常的处理都设计到了,没有完善的有:SQL 的设定、执行,结果的处理。

在JdbcTemplate中找一个使用了这个模板的例子:View Code
从这个方法可以看出来,SQL语句确实由我们提供,这个模板是在执行SQL操作时才指定SQL语句。

这个使用没有对结果的处理
再看查询的例子:
View Code
这个例子,就是包括自定义结果处理的模板使用。

如果我们使用这个方法,处理ResultSet时,还得自己写结果集迭代器。

JdbcTemplate中还提供了一种更简洁的方式:
View Code
PreparedStatement语句模板
View Code
在使用PreparedStatement可能会用到的类有:PreparedStatementCreator:用于指定SQL语句PreparedStatementSetter:用于给SQL语句中的参数赋值
指定SQL:
private static class SimplePreparedStatementCreator implements PreparedStatementCreator, SqlProvider {
private final String sql;
public SimplePreparedStatementCreator(String sql) {
Assert.notNull(sql, "SQL must not be null");
this.sql = sql;
}
public PreparedStatement createPreparedStatement(Connection con) throws SQLException {
return con.prepareStatement(this.sql);
}
public String getSql() {
return this.sql;
}
}
设置参数,也是通过遍历参数数组的方式:
public void setValues(PreparedStatement ps) throws SQLException { if(this.args != null) {
for(int i = 0; i < this.args.length; i++) {
Object arg = this.args[i];
doSetValue(ps, i + 1, arg);
}
}
}
这两个操作都是在内部类中实现的。

CallableStatement语句模板
View Code
这个看起来和前两个有什么不同吗?
接下来看看JdbcTemplate中的其他方法:
如有帮助,欢迎支持。

他们都是在这几个模板方法的基础上对回调接口给出的部分实现而已。

文章整理:融天下p2p网贷系统
11。

相关文档
最新文档