spring技术内幕13-SqlMapClientTemplate对Ibatis的封装
2014-07-17 17:15
507 查看
1、SqlMapClientFactoryBean:
Spring中通过SqlMapClientTemplate提供对Ibatis的支持,与Spring对Hibernate的支持类似,Spring中SqlMapClientFactoryBean就是管理Ibatis的IoC容器,我们首先分析SqlMapClientFactoryBean的源码:
//Spring管理Ibatis的IoC容器
public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>,InitializingBean {
//当前线程绑定Ibtis blob/clob等大字段数据处理器资源
private static final ThreadLocal<LobHandler> configTimeLobHandlerHolder = new ThreadLocal<LobHandler>();
public static LobHandler getConfigTimeLobHandler(){
return configTimeLobHandlerHolder.get();
}
//Ibatis配置文件路径
private Resource[] configLocations;
//Ibatis映射文件路径
private Resource[] mappingLocations;
//Ibatis sqlMapClient属性
private Properties sqlMapClientProperties;
//数据源
private DataSource dataSource;
//使用Spring事务包装数据源
private boolean useTransactionAwareDataSource = true;
//事务配置类
private Class transactionConfigClass = ExternalTransactionConfig.class;
//事务配置属性
private Properties transactionConfigProperties;
//blob/clob等lob类型处理器
private LobHandler lobHandler;
//Ibatis sqlMapClient
private SqlMapClient sqlMapClient;
public SqlMapClientFactoryBean(){
this.transactionConfigProperties = new Properties();
//不允许事务自动提交
this.transactionConfigProperties.setProperty("SetAutoCommitAllowed","false");
}
//指定Ibatis sqlMapClient配置文件路径
public void setConfigLocation(Resource configLocation){
this.configLocations = (configLocation != null ? new Resource[] {configLocation} : null);
}
//指定多个SqlMapClient配置文件路径,这些配置文件在运行时合并
public void setConfigLocations(Resource[] configLocations){
this.configLocations = configLocations;
}
//指定Ibatis映射文件路径,这些映射文件在运行时被合并到SqlMapClient的配置中
public void setMappingLocations(Resource[] mappingLocations){
this.mappingLocations = mappingLocations;
}
//指定Ibatis SqlMapClient可选的属性,即在SqlMapClient配置文件中通过属性文件设置的属性
public void setSqlMapClientProperties(Properties sqlMapClientProperties) {
this.sqlMapClientProperties = sqlMapClientProperties;
}
//设置Ibatis使用的数据源
public void setDataSource(DataSource dataSource){
this.dataSouce = dataSource;
}
//设置数据源是否使用事务包装
public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) {
this.useTransactionAwareDataSource = useTransactionAwareDataSource;
}
//设置Ibatis使用的事务配置类,默认是com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
public void setTransactionConfigClass(Class transactionConfigClass){
if(transactionConfigClass == null || !TransactionConfig.class.isAssignableFrom(transactionConfigClass)){
throw new IllegalArgumentException("Invalid transactionConfigClass: does not imlement " + "com.ibatis.sqlmap.engine.transaction.TransactionConfig");
}
this.transactionConfigClass = transactionConfigClass;
}
//设置Ibatis事务配置类属性
public void setTransactionConfigProperties(Properties transactionConfigProperties){
this.transactionConfigProperties = transactionConfigProperties;
}
//设置Ibatis使用的处理clob/blob等大字段的处理器
public void setLobHandler(LobHandler lobHandler){
this.lobHandler = lobHandler;
}
//IoC容器初始化完成之后的回调方法,是InitializingBean接口的实现方法
public void afterPropertiesSet() throws Exception {
//配置lob处理器
if(this.lobHandler != null){
configTimeLobHandlerHolder.set(this.lobHandler);
}
//创建Ibatis的SqlMapClient
try{
this.sqlMapClient = buildSqlMapClient(this.configLocations,this.mappingLocations,this.sqlMapClientProperties);
//为创建的SqlMapClient设置数据源
if(this.dataSource != null){
//创建事务配置实例
TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass.newInstance();
//获取数据源
DataSource dataSourceToUse = this.dataSource;
//如果Ibatis配置指定使用事务包装的数据源,并且当前获取到的数据源不是事务包装数据源代理类型
if(this.useTransactionAwareDataSource && !(this.dataSource instanceof TransactionAwareDataSourceProxy)){
//为指定数据源创建事务包装代理
dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource);
}
//事务配置对象设置数据源
transactionConfig.setDataSource(dataSourceToUse);
//初始化事务配置对象
transactionConfig.initialize(this.transactionConfigProperties);
}
}
//创建SqlMapClient成功后,清除当前线程绑定的Lob处理器资源
finally{
if(this.lobHandler != null){
configTimeLobHandlerHolder.remove();
}
}
}
//具体创建SqlMapClient的方法,根据给定的Ibatis配置文件、Ibatis映射文件盒Ibatis配置中的属性文件创建SqlMapClient
protected SqlMapClient buildSqlMapClient(Resource[] configLocations,Resource[] mappingLocations,Properties properties) throws IOException {
//如果给定Ibatis配置文件路径为空
if(ObjectUtils.isEmpty(configLocations)){
throw new IllegalArgumentException("At least 1 ' configLocation' entry is required");
}
SqlMapClient client = null;
//创建Ibatis配置文件解析器
SqlMapConfigParser configParser = new SqlMapConfigParser();
//遍历所有的Ibatis配置文件
for(Resource configLocation : configLocations){
//获取Ibatis配置文件输入流
InputStream is = configLocation.getInputStream();
try{
//创建Ibatis SqlMapClient
client = configParser.parse(is,properties);
}
catch(RuntimeException ex){
throw new NestedIOException("Failed to parse config resource: " + configLocation,ex.getCause());
}
}
//如果Ibatis映射文件不为null
if(mappingLocations != null){
//根据Ibatis配置文件解析器创建Ibatis映射文件解析器
SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser);
//遍历所给定的Ibatis映射文件
for(Resource mappingLocation : mappingLocations){
try{
//解析Ibatis映射文件
mapParser.parse(mappingLocation.getInputStream());
}
catch(NodeletException ex){
throw new NestedIOException("Failed to parse mapping resource: " + mappingLocation,ex);
}
}
}
//返回创建的SqlMapClient对象
return client;
}
//将Ibatis配置中指定的事务配置应用到SqlMapClient上
protected void applyTransactionConfig(SqlMapClient sqlMapClient,TransactionConfig transactionConfig){
//如果SqlMapClient不是ExtendedSqlMapClient类型,则无法将Ibatis配置中指定的事务配置应用到SqlMapClient对象
if(!(sqlMapClient instanceof ExtendedSqlMapClient)){
throw new IllegalArgumentException("Cannot set TransactionConfig with DataSource for SqlMapClient if not of type " + "ExtendedSqlMapClient: " + sqlMapClient);
}
ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient)sqlMapClient;
//设置最大并发Ibatis事务数量
transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate().getMaxTransactions());
//为SqlMapClient设置事务处理器
extendedClient.getDelegate().setTxManager(new TransactionManager(transactionConfig));
}
//Spring IoC容器中对应用提供的一个获取被管理对象的方法,应该通过此方法获取被Spring IoC容器管理的Ibatis SqlMapClient对象
public SqlMapClient getObject() {
return this.sqlMapClient;
}
//获取SqlMapClient的类型
public Class<? extends SqlMapClient> getObjectType(){
return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class);
}
//默认Spring IoC容器中管理的对象时单态模式的
public boolean isSingleton(){
return true;
}
//Ibatis映射解析器工厂,内部类
private static class SqlMapParserFactory{
//创建Ibatis映射解析器
public static SqlMapParser createSqlMapParser(SqlMapConfigParser configParser){
XmlParserState state = null;
try{
//使用JDK反射机制获取SqlMapConfigParser类中的state字段
Field stateField = SqlMapConfigParser.class.getDeclaredField("state");
//使用JDK反射机制使state字段可以被访问,主要解决private、protected和默认访问权限没有提供get方法的情况
stateField.setAccessible(true);
//使用Ibatis配置解析器获取指定字段的值
state = (XmlParserState) stateField.get(configParser);
}
catch(Exception ex){
throw new IllegalStateException("iBATIS 2.3.2 'state' field' field not found in SqlMapConfigParser class - " +
"please upgrade to IBATIS 2.3.2 or higher in order to use the new 'mappingLocations' feature. " + ex);
}
//为指定字段值创建Ibatis映射解析器
return new SqlMapParser(state);
}
}
SqlMapClientFactoryBean实现了Spring的FactoryBean接口,是Spring中管理Ibatis的IOC容器,在IoC容器初始化过程中主要完成定位Ibatis配置文件盒Ibatis映射文件等工作。同时SqlMapClientFactoryBean实现了InitializingBean接口,实现了afterPropertiesSet方法,该方法是在IoC容器初始化完成之后由IoC容器进行回调的,在该方法中主要是根据定义的Ibatis配置和映射文件创建Ibatis的SqlMapClient对象的过程。
2、SqlMapClientTemplate:
Spring通过SqlMapClientTemplate对Ibatis一些通用操作做统一的封装处理,同时也对Ibatis的API做了一些封装,方便开发者使用,下面我们继续分析SqlMapClientTemplate对Ibatis封装的实现。
(1)execute方法的实现:
同JdbcTemplate和HibernateTemplate一样,Spring在SqlMapClientTemplate中也是通过execute方法封装Ibatis增删改查的通用操作,同时在execute方法中调用相应的回调对象的回调方法来真正完成Ibatis的处理操作,execute方法源码如下:
public <T> T execute(SqlMapClientCallback<T> action) throws DataAccessException {
Assert.notNull(action,"Callback object must not be null");
Assert.notNull(this.sqlMapClient,"No SqlMapClient specified");
//通过SqlMapClient对象打开一个Ibatis SqlMapSession
SqlMapSession session = this.sqlMapClient.openSession();
if(logger.isDebugEnabled()){
logger.debug("Opened SqlMapSession [ " + session + "] for iBATIS operation");
}
Connection ibatsCon = null;
try{
Connection springCon = null;
//获取数据源
DataSource dataSource = getDataSource();
//根据数据源是否事务包装数据源代理类型,判断数据源是否需要事务包装
boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy);
try{
//获取连接
ibatisCon = session.getCurrentConnection();
//如果当前Ibatis SqlMapSession还没有创建过连接
if(ibatisCon == null){
//如果Ibatis数据源已经在Spring事务管理之下,则直接使用数据源创建连接,否则,使用DataSourceUtils创建连接,并且创建的连接置于Spring事务管理之中
springCon = (transactionAware ? dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource));
session.setUserConnection(springCon);
if(logger.isDebugEnabled()){
logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation");
}
}
//如果当前Ibatis SqlMapSession已经创建过连接,则直接使用
else {
if(logger.isDebugEnabled()){
logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for IBATIS operation");
}
}
}
catch(SQLException ex){
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection",ex);
}
//调用具体增删改查操作回调对象的方法
try{
return action.doInSqlMapClient(session);
}
catch(SQLException ex){
throw getExceptionTranslator().translate("SqlMapClient operation",null,ex);
}
finally{
try{
//释放连接
if(springCon != null){
if(transactionAware){
springCon.close();
}
else{
DataSourceUtils.doReleaseConnection(springCon,dataSource);
}
}
}
catch(Throwable ex){
logger.debug("Could not close JDBC Connection",ex);
}
}
}
//关闭Ibatis的SqlMapSession
finally{
if(ibatisCon == null){
session.close();
}
}
}
(2)Spring封装Ibatis API的方法:
我们以Spring的queryForObject方法为例,分析Spring封装Ibatis API的实现,源码如下:
//查询对象
public Object queryForObject(final String statementName,final Object parameterObject) throws DataAccessException {
//调用execute方法,参数是实现了SqlMapClientCallback接口的匿名内部类,execute方法中回调该对象的doInSqlMapClient方法
return execute(new SqlMapClientCallback<Object>(){
//真正调用Ibatis API做具体操作处理的方法
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
//调用Ibatis SqlMapSession对象的queryForObject方法
return executor.queryForObject(statementName,parameterObject);
}
});
}
Spring中通过SqlMapClientTemplate提供对Ibatis的支持,与Spring对Hibernate的支持类似,Spring中SqlMapClientFactoryBean就是管理Ibatis的IoC容器,我们首先分析SqlMapClientFactoryBean的源码:
//Spring管理Ibatis的IoC容器
public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>,InitializingBean {
//当前线程绑定Ibtis blob/clob等大字段数据处理器资源
private static final ThreadLocal<LobHandler> configTimeLobHandlerHolder = new ThreadLocal<LobHandler>();
public static LobHandler getConfigTimeLobHandler(){
return configTimeLobHandlerHolder.get();
}
//Ibatis配置文件路径
private Resource[] configLocations;
//Ibatis映射文件路径
private Resource[] mappingLocations;
//Ibatis sqlMapClient属性
private Properties sqlMapClientProperties;
//数据源
private DataSource dataSource;
//使用Spring事务包装数据源
private boolean useTransactionAwareDataSource = true;
//事务配置类
private Class transactionConfigClass = ExternalTransactionConfig.class;
//事务配置属性
private Properties transactionConfigProperties;
//blob/clob等lob类型处理器
private LobHandler lobHandler;
//Ibatis sqlMapClient
private SqlMapClient sqlMapClient;
public SqlMapClientFactoryBean(){
this.transactionConfigProperties = new Properties();
//不允许事务自动提交
this.transactionConfigProperties.setProperty("SetAutoCommitAllowed","false");
}
//指定Ibatis sqlMapClient配置文件路径
public void setConfigLocation(Resource configLocation){
this.configLocations = (configLocation != null ? new Resource[] {configLocation} : null);
}
//指定多个SqlMapClient配置文件路径,这些配置文件在运行时合并
public void setConfigLocations(Resource[] configLocations){
this.configLocations = configLocations;
}
//指定Ibatis映射文件路径,这些映射文件在运行时被合并到SqlMapClient的配置中
public void setMappingLocations(Resource[] mappingLocations){
this.mappingLocations = mappingLocations;
}
//指定Ibatis SqlMapClient可选的属性,即在SqlMapClient配置文件中通过属性文件设置的属性
public void setSqlMapClientProperties(Properties sqlMapClientProperties) {
this.sqlMapClientProperties = sqlMapClientProperties;
}
//设置Ibatis使用的数据源
public void setDataSource(DataSource dataSource){
this.dataSouce = dataSource;
}
//设置数据源是否使用事务包装
public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) {
this.useTransactionAwareDataSource = useTransactionAwareDataSource;
}
//设置Ibatis使用的事务配置类,默认是com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig
public void setTransactionConfigClass(Class transactionConfigClass){
if(transactionConfigClass == null || !TransactionConfig.class.isAssignableFrom(transactionConfigClass)){
throw new IllegalArgumentException("Invalid transactionConfigClass: does not imlement " + "com.ibatis.sqlmap.engine.transaction.TransactionConfig");
}
this.transactionConfigClass = transactionConfigClass;
}
//设置Ibatis事务配置类属性
public void setTransactionConfigProperties(Properties transactionConfigProperties){
this.transactionConfigProperties = transactionConfigProperties;
}
//设置Ibatis使用的处理clob/blob等大字段的处理器
public void setLobHandler(LobHandler lobHandler){
this.lobHandler = lobHandler;
}
//IoC容器初始化完成之后的回调方法,是InitializingBean接口的实现方法
public void afterPropertiesSet() throws Exception {
//配置lob处理器
if(this.lobHandler != null){
configTimeLobHandlerHolder.set(this.lobHandler);
}
//创建Ibatis的SqlMapClient
try{
this.sqlMapClient = buildSqlMapClient(this.configLocations,this.mappingLocations,this.sqlMapClientProperties);
//为创建的SqlMapClient设置数据源
if(this.dataSource != null){
//创建事务配置实例
TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass.newInstance();
//获取数据源
DataSource dataSourceToUse = this.dataSource;
//如果Ibatis配置指定使用事务包装的数据源,并且当前获取到的数据源不是事务包装数据源代理类型
if(this.useTransactionAwareDataSource && !(this.dataSource instanceof TransactionAwareDataSourceProxy)){
//为指定数据源创建事务包装代理
dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource);
}
//事务配置对象设置数据源
transactionConfig.setDataSource(dataSourceToUse);
//初始化事务配置对象
transactionConfig.initialize(this.transactionConfigProperties);
}
}
//创建SqlMapClient成功后,清除当前线程绑定的Lob处理器资源
finally{
if(this.lobHandler != null){
configTimeLobHandlerHolder.remove();
}
}
}
//具体创建SqlMapClient的方法,根据给定的Ibatis配置文件、Ibatis映射文件盒Ibatis配置中的属性文件创建SqlMapClient
protected SqlMapClient buildSqlMapClient(Resource[] configLocations,Resource[] mappingLocations,Properties properties) throws IOException {
//如果给定Ibatis配置文件路径为空
if(ObjectUtils.isEmpty(configLocations)){
throw new IllegalArgumentException("At least 1 ' configLocation' entry is required");
}
SqlMapClient client = null;
//创建Ibatis配置文件解析器
SqlMapConfigParser configParser = new SqlMapConfigParser();
//遍历所有的Ibatis配置文件
for(Resource configLocation : configLocations){
//获取Ibatis配置文件输入流
InputStream is = configLocation.getInputStream();
try{
//创建Ibatis SqlMapClient
client = configParser.parse(is,properties);
}
catch(RuntimeException ex){
throw new NestedIOException("Failed to parse config resource: " + configLocation,ex.getCause());
}
}
//如果Ibatis映射文件不为null
if(mappingLocations != null){
//根据Ibatis配置文件解析器创建Ibatis映射文件解析器
SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser);
//遍历所给定的Ibatis映射文件
for(Resource mappingLocation : mappingLocations){
try{
//解析Ibatis映射文件
mapParser.parse(mappingLocation.getInputStream());
}
catch(NodeletException ex){
throw new NestedIOException("Failed to parse mapping resource: " + mappingLocation,ex);
}
}
}
//返回创建的SqlMapClient对象
return client;
}
//将Ibatis配置中指定的事务配置应用到SqlMapClient上
protected void applyTransactionConfig(SqlMapClient sqlMapClient,TransactionConfig transactionConfig){
//如果SqlMapClient不是ExtendedSqlMapClient类型,则无法将Ibatis配置中指定的事务配置应用到SqlMapClient对象
if(!(sqlMapClient instanceof ExtendedSqlMapClient)){
throw new IllegalArgumentException("Cannot set TransactionConfig with DataSource for SqlMapClient if not of type " + "ExtendedSqlMapClient: " + sqlMapClient);
}
ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient)sqlMapClient;
//设置最大并发Ibatis事务数量
transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate().getMaxTransactions());
//为SqlMapClient设置事务处理器
extendedClient.getDelegate().setTxManager(new TransactionManager(transactionConfig));
}
//Spring IoC容器中对应用提供的一个获取被管理对象的方法,应该通过此方法获取被Spring IoC容器管理的Ibatis SqlMapClient对象
public SqlMapClient getObject() {
return this.sqlMapClient;
}
//获取SqlMapClient的类型
public Class<? extends SqlMapClient> getObjectType(){
return (this.sqlMapClient != null ? this.sqlMapClient.getClass() : SqlMapClient.class);
}
//默认Spring IoC容器中管理的对象时单态模式的
public boolean isSingleton(){
return true;
}
//Ibatis映射解析器工厂,内部类
private static class SqlMapParserFactory{
//创建Ibatis映射解析器
public static SqlMapParser createSqlMapParser(SqlMapConfigParser configParser){
XmlParserState state = null;
try{
//使用JDK反射机制获取SqlMapConfigParser类中的state字段
Field stateField = SqlMapConfigParser.class.getDeclaredField("state");
//使用JDK反射机制使state字段可以被访问,主要解决private、protected和默认访问权限没有提供get方法的情况
stateField.setAccessible(true);
//使用Ibatis配置解析器获取指定字段的值
state = (XmlParserState) stateField.get(configParser);
}
catch(Exception ex){
throw new IllegalStateException("iBATIS 2.3.2 'state' field' field not found in SqlMapConfigParser class - " +
"please upgrade to IBATIS 2.3.2 or higher in order to use the new 'mappingLocations' feature. " + ex);
}
//为指定字段值创建Ibatis映射解析器
return new SqlMapParser(state);
}
}
SqlMapClientFactoryBean实现了Spring的FactoryBean接口,是Spring中管理Ibatis的IOC容器,在IoC容器初始化过程中主要完成定位Ibatis配置文件盒Ibatis映射文件等工作。同时SqlMapClientFactoryBean实现了InitializingBean接口,实现了afterPropertiesSet方法,该方法是在IoC容器初始化完成之后由IoC容器进行回调的,在该方法中主要是根据定义的Ibatis配置和映射文件创建Ibatis的SqlMapClient对象的过程。
2、SqlMapClientTemplate:
Spring通过SqlMapClientTemplate对Ibatis一些通用操作做统一的封装处理,同时也对Ibatis的API做了一些封装,方便开发者使用,下面我们继续分析SqlMapClientTemplate对Ibatis封装的实现。
(1)execute方法的实现:
同JdbcTemplate和HibernateTemplate一样,Spring在SqlMapClientTemplate中也是通过execute方法封装Ibatis增删改查的通用操作,同时在execute方法中调用相应的回调对象的回调方法来真正完成Ibatis的处理操作,execute方法源码如下:
public <T> T execute(SqlMapClientCallback<T> action) throws DataAccessException {
Assert.notNull(action,"Callback object must not be null");
Assert.notNull(this.sqlMapClient,"No SqlMapClient specified");
//通过SqlMapClient对象打开一个Ibatis SqlMapSession
SqlMapSession session = this.sqlMapClient.openSession();
if(logger.isDebugEnabled()){
logger.debug("Opened SqlMapSession [ " + session + "] for iBATIS operation");
}
Connection ibatsCon = null;
try{
Connection springCon = null;
//获取数据源
DataSource dataSource = getDataSource();
//根据数据源是否事务包装数据源代理类型,判断数据源是否需要事务包装
boolean transactionAware = (dataSource instanceof TransactionAwareDataSourceProxy);
try{
//获取连接
ibatisCon = session.getCurrentConnection();
//如果当前Ibatis SqlMapSession还没有创建过连接
if(ibatisCon == null){
//如果Ibatis数据源已经在Spring事务管理之下,则直接使用数据源创建连接,否则,使用DataSourceUtils创建连接,并且创建的连接置于Spring事务管理之中
springCon = (transactionAware ? dataSource.getConnection() : DataSourceUtils.doGetConnection(dataSource));
session.setUserConnection(springCon);
if(logger.isDebugEnabled()){
logger.debug("Obtained JDBC Connection [" + springCon + "] for iBATIS operation");
}
}
//如果当前Ibatis SqlMapSession已经创建过连接,则直接使用
else {
if(logger.isDebugEnabled()){
logger.debug("Reusing JDBC Connection [" + ibatisCon + "] for IBATIS operation");
}
}
}
catch(SQLException ex){
throw new CannotGetJdbcConnectionException("Could not get JDBC Connection",ex);
}
//调用具体增删改查操作回调对象的方法
try{
return action.doInSqlMapClient(session);
}
catch(SQLException ex){
throw getExceptionTranslator().translate("SqlMapClient operation",null,ex);
}
finally{
try{
//释放连接
if(springCon != null){
if(transactionAware){
springCon.close();
}
else{
DataSourceUtils.doReleaseConnection(springCon,dataSource);
}
}
}
catch(Throwable ex){
logger.debug("Could not close JDBC Connection",ex);
}
}
}
//关闭Ibatis的SqlMapSession
finally{
if(ibatisCon == null){
session.close();
}
}
}
(2)Spring封装Ibatis API的方法:
我们以Spring的queryForObject方法为例,分析Spring封装Ibatis API的实现,源码如下:
//查询对象
public Object queryForObject(final String statementName,final Object parameterObject) throws DataAccessException {
//调用execute方法,参数是实现了SqlMapClientCallback接口的匿名内部类,execute方法中回调该对象的doInSqlMapClient方法
return execute(new SqlMapClientCallback<Object>(){
//真正调用Ibatis API做具体操作处理的方法
public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException {
//调用Ibatis SqlMapSession对象的queryForObject方法
return executor.queryForObject(statementName,parameterObject);
}
});
}
相关文章推荐
- 《Spring技术内幕》学习笔记13——SqlMapClientTemplate对Ibatis的封装
- 《Spring技术内幕》学习笔记13——SqlMapClientTemplate对Ibatis的封装
- 《Spring技术内幕》学习笔记13——SqlMapClientTemplate对Ibatis的封装
- 《Spring技术内幕》学习笔记13——SqlMapClientTemplate对Ibatis的封装
- ibatis+spring+struts spring 外部注入 SqlMapClientTemplate
- SqlMapClientTemplate对Ibatis的封装
- spring_150906_sqlmapclientdaosupport_getSqlMapClientTemplate
- 整合iBatis和Spring之SqlMapClientDaoSupport
- Spring整合Ibatis之SqlMapClientDaoSupport
- Spring整个Ibatis之SqlMapClientDaoSupport
- Ibatis,Spring注解方式注入sqlMapClient
- Spring整个Ibatis之SqlMapClientDaoSupport
- Ibatis,Spring注解方式注入sqlMapClient
- 在spring中使用SqlMapClientTemplate操作数据库
- Spring中的Ibatis之SqlMapClientDaoSupport
- Ibatis中SqlMapClientTemplate和SqlMapClient的区别
- SPRING技术内幕-笔记(十二)spring驱动ibatis的设计与实现
- Spring整合Ibatis之SqlMapClientDaoSupport
- ibatis之SqlMapClientTemplate和SqlMapClient
- spring技术内幕12-HibernateTemplate对Hibernate的封装