- 浏览: 88995 次
- 性别:
- 来自: 厦门
最新评论
-
zhengyong7232:
SELECT t.province,DECODE(landsc ...
列转行 -
meepo3927:
不是特么很懂
列转行
1. SqlMapClientFactoryBean :
Spring 中通过 SqlMapClientTemplate 提供对 Ibatis 的支持,与 Spring 对 Hibernate 的支持类似, Spring 中 SqlMapClientFactoryBean 就是管理 Ibatis 的 IoC 容器,我们首先分析 SqlMapClientFactoryBean 的源码:
//Spring管理Ibatis的IoC容器
public class SqlMapClientFactoryBean implements FactoryBean<SqlMapClient>, InitializingBean {
//当前线程绑定Ibatis 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.dataSource = 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 implement " +
"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);
applyTransactionConfig(this.sqlMapClient, transactionConfig);
}
}
//创建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、//protect和默认访问权限没有提供get方法的情况
stateField.setAccessible(true);
//使用Ibatis配置解析器获取指定字段的值
state = (XmlParserState) stateField.get(configParser);
}
catch (Exception ex) {
throw new IllegalStateException("iBATIS 2.3.2 'state' 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);
}
}
195.}
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 ibatisCon = 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对象的queryForObejct方法
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 {
//当前线程绑定Ibatis 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.dataSource = 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 implement " +
"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);
applyTransactionConfig(this.sqlMapClient, transactionConfig);
}
}
//创建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、//protect和默认访问权限没有提供get方法的情况
stateField.setAccessible(true);
//使用Ibatis配置解析器获取指定字段的值
state = (XmlParserState) stateField.get(configParser);
}
catch (Exception ex) {
throw new IllegalStateException("iBATIS 2.3.2 'state' 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);
}
}
195.}
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 ibatisCon = 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对象的queryForObejct方法
return executor.queryForObject(statementName, parameterObject);
}
});
}
发表评论
-
最小生成树之Kruskal算法
2013-12-15 00:54 1086这篇文章实现最小生成树的Kruskal算法Kruskal算 ... -
排序算法--插入排序
2013-12-15 00:47 1065插入排序原理:假设 ... -
poi创建下拉框
2013-04-16 19:01 0package finance.tools.salesper ... -
Spring中Transactional配置
2013-04-11 20:43 1001Spring中Transactional配置 标签: 杂谈 分 ... -
Hibernate将Enum枚举类型映射为Int类型 .
2013-04-09 16:46 1538最近要用Hibernate做一个枚举类型的映射,在MySQL ... -
Hibernate 更灵活的用法 HibernateCallback
2013-01-22 14:41 1433在项目中用Hibernate的DetachedCriter ... -
spring源代码分析(2)--BeanFactory
2013-01-20 12:38 1430我们首先来看下BeanFacroty接口 pa ... -
spring源代码分析(1)--Resource的分析
2013-01-20 12:22 4044我们知道,在spring中,配置文件是通过资源形式加载的, ... -
DefaultListableBeanFactory研究
2013-01-18 10:49 5907DefaultSingletonBeanRegistry完 ... -
jvm的内存调优
2013-01-11 15:54 8631) 堆 运行时数 ... -
struts2中Action的name 和package的name和namespace是什么作用
2013-01-02 12:16 9635在struts2的 struts.xml 配置中 例: ... -
深入探索 高效的Java异常处理框架
2012-10-22 14:09 913摘要:本文从Java异常最基本的概念、语法开始讲述了Java异 ... -
JAVA对ArrayList排序
2012-10-16 21:53 16519java如何对ArrayList中对象按照该对象某属性排序 ... -
ThreadPoolExecutor使用和思考(中)-keepAliveTime及拒绝策略
2012-09-11 00:48 956工作中多处接触到了ThreadPoolExecutor。趁着现 ... -
ThreadPoolExecutor使用和思考(上)-线程池大小设置与BlockingQueue的三种实现区别
2012-09-11 00:45 1652工作中多处接触到了ThreadPoolExecutor。趁着现 ... -
Spring IOC之BeanFactory
2012-09-10 12:39 1311BeanFactory ,作为 Spring 基础的 IoC ... -
Java5 并发学习
2012-09-10 11:33 820在Java5之后 ... -
Spring对事务管理的支持的发展历程(基础篇
2012-08-31 17:43 939Connection conn = DataS ... -
CXF ,在Client端用于把 Date 类型转换成 XMLGregorianCalendar .
2012-08-31 16:54 1656import javax.xml.datatype.Datat ... -
《Spring技术内幕》学习笔记10——Web环境中Spring的启动过程
2012-07-30 09:04 10031.Spring 不但可以在 JavaSE 环境中应用,在 W ...
相关推荐
标题中的“Spring技术内幕 学习笔记”表明这是一份关于深入理解Spring框架核心机制的资料集合,主要关注Spring框架的内部工作原理和高级用法。描述中的“NULL”没有提供额外信息,但我们可以通过标签“源码”和...
最近想在最新的Spring5.0中集成ibatis(不是mybatis),发现已经不在支持SqlmapClientTemplate和SqlmapClientFactoryBean,于是搞了这个工具jar来进行支持如下配置 <bean id="sqlMapClient" class="org.spring...
### Spring对IBatis的整合 #### 一、Spring与IBatis整合概述 Spring框架与IBatis(现称为MyBatis)的整合为开发者提供了一种更简洁、更强大的数据库访问方式。Spring通过其内置的支持机制极大地简化了原有的IBatis...
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> ``` 接着,我们需要创建iBATIS的SQL映射文件(如`sqlMapConfig.xml`),在这个文件中,我们将定义数据库的SQL...
在软件开发领域,特别是Java企业级应用开发中,Spring框架和iBATIS(现已更名为MyBatis)是非常重要的两个技术组件。Spring作为一款全面的企业级应用解决方案,其核心功能包括依赖注入、面向切面编程以及容器管理等...
`SqlMapClientTemplate`是Spring提供的模板类,封装了数据库操作,使得代码更加简洁、易维护。 3. **声明式事务管理** 声明式事务管理是Spring的一个强大特性,它允许我们在不修改业务逻辑代码的情况下,通过配置...
Spring还包含了对其他许多框架的集成功能,比如对Struts1和iBatis的支持。在本示例中,Spring将负责管理Action和DAO的生命周期,以及数据源和事务的配置。 集成这三个框架的基本步骤包括: 1. 配置Struts1:在...
在Spring中,我们可以通过`SqlMapClientDaoSupport`类或者`SqlMapClientTemplate`类来实现对iBatis的集成。 - `SqlMapClientDaoSupport`是一个抽象类,它实现了`DaoSupport`接口,可以被继承并提供一些方便的方法来...
<bean id="userMapper" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> ``` 7. **声明式事务管理**:Spring提供了声明式事务管理,我们可以在方法级别或类级别通过@Transactional注解来控制...
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> ``` 这样就完成了Spring与ibatis的完全整合。 #### 五、总结 通过以上步骤,我们成功地实现了ibatis与Spring...
`sqlMapClientTemplate`是Spring封装的模板类,用于执行iBatis的SQL映射。 7. iBatis的sqlmap-config.xml配置文件 iBatis的配置文件通常包含数据源配置、事务管理器以及SQL映射文件的路径: ```xml ${jdbc....
【Spring与iBATIS的集成】是Java开发中一个常见的技术组合,主要目的是为了实现对象关系映射(ORM)的功能,使开发者能够更方便地在Java应用中操作数据库。iBATIS虽然不像Hibernate那样广受欢迎,但其独特之处在于它...
`SqlMapClientTemplate`是实际执行SQL操作的工具,它封装了执行SQL映射文件中定义的查询和更新的方法。 为了在Spring中配置iBATIS,我们需要在Spring的配置文件(如`beans.xml`)中声明`SqlMapClient` bean,并指定...
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> ``` 并创建抽象的`SqlMapClientDaoSupport`,作为其他DAO类的基类,注入`sqlMapClientTemplate`: ```xml ...
Spring 框架作为一个流行的 Java Web 应用程序框架,提供了许多灵活的配置和集成功能,其中包括对 iBatis 的集成。iBatis 是一个流行的持久层框架,提供了高效的数据访问和映射功能。在本篇文章中,我们将详细介绍...
同样,它也支持Spring中的SqlMapClientTemplate。 **总结** iBatis Plugin作为IntelliJ IDEA中的得力助手,它有效地减轻了开发者在使用iBatis框架时的负担,提升了开发效率。从代码生成到智能提示,每一个细节都...
### Struts2、Spring 和 iBatis 的整合 #### 1. Spring 和 iBatis 整合步骤 - **配置 Spring 定义文件**: - 在 `src` 目录下编写 Spring 配置文件,使用 `SqlMapClientFactoryBean` 完成 SqlMapClient 的定义。 ...
<bean id="sqlMapClientTemplate" class="org.springframework.orm.ibatis.SqlMapClientTemplate"> <!-- 配置 transactionManager事物管理--> <bean id="transactionManager" class="org.springframework....
3. **8.3 集成iBATIS**:Spring与iBATIS的集成主要通过SqlMapClientTemplate来实现,使得在Spring环境中可以方便地使用iBATIS的XML映射文件和动态SQL。 4. **8.4 集成JPA**:Spring支持JPA(Java Persistence API)...