0x01 为什么会有JdbcTemplate
原因一:代码重复性
JDBC编程需要我们获取数据库连接,然后进行增删改查,最后关闭一些资源,然后还要捕获异常。那么这些代码都是重复的,我们可以通过模板方法模式
去简化这些代码
原因二:异常体系
根据JDBC规范,不同实现厂商会抛出SQLException
异常,这个异常通过ErrorCode
来区分不同错误,但是不同厂商针对同一个错误提供的ErrorCode
可能不同,那么需要我们统一处理这些差异
JdbcTemplate
就解决了上述两个问题。
0x02 相关类讲解
JdbcTemplate
继承了JdbcAccessor
类,并实现了JdbcOprations
接口。
JdbcOprations
该接口提供了所有JDBC相关需要实现的方法
JdbcAccessor
该类是一个抽象类。
实现了Spring的InitializingBean
接口,在afterPropertiesSet
方法中,根据lazyInit
属性加载异常转换器(就是将不同ErrorCode
的SQLException
封装成Spring的DataAccessException
),调用的方法是getExceptionTranslator
方法
public synchronized SQLExceptionTranslator getExceptionTranslator() {
if (this.exceptionTranslator == null) {
DataSource dataSource = getDataSource();
if (dataSource != null) {
this.exceptionTranslator = new SQLErrorCodeSQLExceptionTranslator(dataSource);
}
else {
this.exceptionTranslator = new SQLStateSQLExceptionTranslator();
}
}
return this.exceptionTranslator;
}
DataSource
是在JDBC2.0之后引入的,代替了DriverManager
的数据库连接创建方式
JdbcTemplate
该类采用了模板方法模式
,同时配合回调方法
// 该方法会被其他方法调用
// 比如query方法,query方法中会有实现StatementCallback接口的一个query内部类
@Override
public <T> T execute(StatementCallback<T> action) throws DataAccessException {
Assert.notNull(action, "Callback object must not be null");
// 此处通过该工具类获取Connection会被绑定在当前线程中,以便Spring的统一事务使用
Connection con = DataSourceUtils.getConnection(getDataSource(