[size=medium]
SqlMapClient是iBatis 2.x操作数据库的主要类,相当于hibernate的Session。
Spring创建iBatis的SqlMapClient实例是通过SqlMapClientFactoryBean.afterPropertiesSet方法创建的,由于SqlMapClientFactoryBean实现InitializingBean接口,IoC容器会在依赖注入完成后回调InitializingBean接口的afterPropertiesSet。
applicationContext.xml配置sqlMapClient
<bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation">
<value>classpath:sqlMapConfig.xml</value>
</property>
</bean>
SqlMapClientFactoryBean通过的getObject()返回sqlMapClient,跟其他的FactoryBean一样。
生成的过程afterPropertiesSet方法
public void afterPropertiesSet() throws Exception {
/*设置自定义的lobHandler,LobHandler为操作二进制字段和大文本字段提供统一接口访问,如Oracle LOB*/
if (this.lobHandler != null) {
/*当前线程绑定Ibatis blob/clob等大字段数据处理器资源 */
configTimeLobHandlerHolder.set(this.lobHandler);
}
try {
/*创建iBatis的sqlMapClient相当于hibernate的Session,是iBatis操作数据库的主要类*/ this.sqlMapClient = buildSqlMapClient(this.configLocations, this.mappingLocations, this.sqlMapClientProperties);
// Tell the SqlMapClient to use the given DataSource, if any.
/*设置dataSource数据源*/
if (this.dataSource != null) {
TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass.newInstance();
DataSource dataSourceToUse = this.dataSource;
if (this.useTransactionAwareDataSource && !(this.dataSource instanceof TransactionAwareDataSourceProxy)) {
/*生成事务数据源的动态代理*/
dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource);
}
//为事务配置对象设置数据源
transactionConfig.setDataSource(dataSourceToUse);
//为事务配置对象设置属性
transactionConfig.initialize(this.transactionConfigProperties);
applyTransactionConfig(this.sqlMapClient, transactionConfig);
}
}
finally {
if (this.lobHandler != null) {
// Reset LobHandler holder.
configTimeLobHandlerHolder.remove();
}
}
}
具体sqlMapClient创建的过程
/*根据iBatis的配置文档sqlMapConfig.xml、映射文档如User.xml和属性文档生成sqlMapClient
* */
protected SqlMapClient buildSqlMapClient(
Resource[] configLocations, Resource[] mappingLocations, Properties properties)
throws IOException {
/*判断配置文档是否为空*/
if (ObjectUtils.isEmpty(configLocations)) {
throw new IllegalArgumentException("At least 1 'configLocation' entry is required");
}
SqlMapClient client = null;
/*生成配置文档解析器*/
SqlMapConfigParser configParser = new SqlMapConfigParser();
for (Resource configLocation : configLocations) {
/*获取配置文档的输入流*/
InputStream is = configLocation.getInputStream();
try {
/*生成sqlMapClient*/
client = configParser.parse(is, properties);
}
catch (RuntimeException ex) {
throw new NestedIOException("Failed to parse config resource: " + configLocation, ex.getCause());
}
}
if (mappingLocations != null) {
/*创建映射文档的解析器,自己可以在createSqlMapParser中做一些自定义处理,如通过反射方式设置缓冲配置*/
SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser);
for (Resource mappingLocation : mappingLocations) {
try {
mapParser.parse(mappingLocation.getInputStream());
}
catch (NodeletException ex) {
throw new NestedIOException("Failed to parse mapping resource: " + mappingLocation, ex);
}
}
}
return client;
}
[/size]