在JAVA的设计模式中有一种模式叫模板设计模式,所谓模板,顾名思义,一般就是指准备好了一个固定的模型,使用时套用即可。但在JAVA的设计模式中,还是有点不同,这里的不同主要是“套用”的内容不同,在设计模式中的“套用”,套用的是步骤,并且模板中的某些步骤,是需要使用者自己实现的。举例如下:
//这是一个CPU的计算器模板类
public class CpuCalculator(){
//这是给其他类使用的模板方法,在模板方法中规定了步骤
public int calculte(){
this.loadDateFromMemory();
this.preDoSomething();
this.doCalculte();
this.postDoSomething();
}
//这些是需要子类实现的计算步骤
protected abstract loadDateFromMemory();
protected abstract preDoSomething();
protected abstract doCalculte();
protected abstract postDoSomething();
}
按照上述理解,我们看看今天的主角 org.springframework.jdbc.core.JdbcTemplate,它为什么是模板?
/**
* <b>This is the central class in the JDBC core package.</b>
* It simplifies the use of JDBC and helps to avoid common errors.
* It executes core JDBC workflow, leaving application code to provide SQL
* and extract results. This class executes SQL queries or updates, initiating
* iteration over ResultSets and catching JDBC exceptions and translating
* them to the generic, more informative exception hierarchy defined in the
* org.springframework.dao package.
*
* <p>Code using this class need only implement callback interfaces, giving
* them a clearly defined contract. The PreparedStatementCreator callback
* interface creates a prepared statement given a Connection provided by this
* class, providing SQL and any necessary parameters. The RowCallbackHandler
* interface extracts values from each row of a ResultSet.
*
* <p>Can be used within a service implementation via direct instantiation
* with a DataSource reference, or get prepared in an application context
* and given to services as bean reference. Note: The DataSource should
* always be configured as a bean in the application context, in the first case
* given to the service directly, in the second case to the prepared template.
*
* <p>The motivation and design of this class is discussed
* in detail in
* <a href="http://www.amazon.com/exec/obidos/tg/detail/-/0764543857/">Expert One-On-One J2EE Design and Development</a>
* by Rod Johnson (Wrox, 2002).
*
* <p>Because this class is parameterizable by the callback interfaces and
* the SQLExceptionTranslator interface, it isn't necessary to subclass it.
* All SQL issued by this class is logged.
*
* @author Rod Johnson
* @author Juergen Hoeller
* @author Yann Caroff
* @author Thomas Risberg
* @author Isabelle Muszynski
* @version $Id: JdbcTemplate.java,v 1.37 2004/03/23 22:48:38 jhoeller Exp $
* @since May 3, 2001
* @see org.springframework.dao
* @see org.springframework.jdbc.datasource
* @see org.springframework.jdbc.object
*/
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations, InitializingBean {
。。。。
}
在上面的源码注释中,最能体现模板模式的一句话就是:
It executes core JDBC workflow, leaving application code to provide SQLand extract results.
简单翻译一下就是:这个类负责执行核心的JDBC工作流程,业务应用只需要提供SQL语句和处理返回结果即可。那注释里说的这个核心流程是指哪个方法呢?如下:
//-------------------------------------------------------------------------
// Methods dealing with static SQL (java.sql.Statement)
//-------------------------------------------------------------------------
public Object execute(final StatementCallback action) {
//1、获取数据源连接
Connection con = DataSourceUtils.getConnection(getDataSource());
Statement stmt = null;
try {
Connection conToUse = con;
if (this.nativeJdbcExtractor != null &&
this.nativeJdbcExtractor.isNativeConnectionNecessaryForNativeStatements()) {
conToUse = this.nativeJdbcExtractor.getNativeConnection(con);
}
//2、准被语句声明,对sql进行预处理
stmt = conToUse.createStatement();
DataSourceUtils.applyTransactionTimeout(stmt, getDataSource());
Statement stmtToUse = stmt;
if (this.nativeJdbcExtractor != null) {
stmtToUse = this.nativeJdbcExtractor.getNativeStatement(stmt);
}
//3、执行
Object result = action.doInStatement(stmtToUse);
SQLWarning warning = stmt.getWarnings();
throwExceptionOnWarningIfNotIgnoringWarnings(warning);
return result;
}
catch (SQLException ex) {
throw getExceptionTranslator().translate("executing StatementCallback", null, ex);
}
finally {
//4、关闭声明和结果集
JdbcUtils.closeStatement(stmt);
//5、关闭连接
DataSourceUtils.closeConnectionIfNecessary(con, getDataSource());
}
}
代码中的1-5步,就是所谓的模板这个的步骤,其中使用者只需要关注和实现第3步,以及对返回结果的处理。
正如注释中所说:Leaving application code to provide SQLand extract results
让使用模板的用户只关注核心业务,就是模板模式的应有之意。