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]