?
Ce document utilise Manuel du site Web PHP chinois Libérer
在Spring框架中,iBatis的支持很類似JDBC或者Hibernate的支持,因?yàn)樗蚃DBC或Hibernate一樣支持相同的模板式編程, iBatis的支持能與Spring的異常體系一起工作并讓你享用所有Spring的Ioc特點(diǎn)。
事務(wù)管理可以由Spring標(biāo)準(zhǔn)機(jī)制進(jìn)行處理。對(duì)于iBATIS來說沒有特別的事務(wù)策略,除了JDBC
Connection
以外,也沒有特別的事務(wù)資源。因此,Spring
標(biāo)準(zhǔn)的JDBC DataSourceTransactionManager
或者
JtaTransactionManager
已經(jīng)能夠完全足夠了。
Spring的確支持iBatis的1.x和2.x.但是,只有iBatis 2.x的支持包含在核心Spring發(fā)布版本中。 iBatis1.x的支持類被轉(zhuǎn)移到Spring 2.0的Spring Modules project,你可以在那里找到文檔指導(dǎo)。
如果我們希望使用iBATIS 2.x來映射剛才的那個(gè)Account類,則需要?jiǎng)?chuàng)建這樣一個(gè)SQL map Account.xml
:
<sqlMap namespace="Account"> <resultMap id="result" class="examples.Account"> <result property="name" column="NAME" columnIndex="1"/> <result property="email" column="EMAIL" columnIndex="2"/> </resultMap> <select id="getAccountByEmail" resultMap="result"> select ACCOUNT.NAME, ACCOUNT.EMAIL from ACCOUNT where ACCOUNT.EMAIL = #value# </select> <insert id="insertAccount"> insert into ACCOUNT (NAME, EMAIL) values (#name#, #email#) </insert> </sqlMap>
iBATIS2的配置文件看起來像這樣:
<sqlMapConfig> <sqlMap resource="example/Account.xml"/> </sqlMapConfig>
記住iBATIS從CLASSPATH下加載資源,所以必須確保 Account.xml
在CLASSPATH下。
我們可以使用Spring container中的 SqlMapClientFactoryBean
。
注意iBATIS SQL Map 2.x中,JDBC DataSource
通常由
SqlMapClientFactoryBean
指定,并開啟了延遲加載。
<beans> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driverClassName}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean"> <property name="configLocation" value="WEB-INF/sqlmap-config.xml"/> <property name="dataSource" ref="dataSource"/> </bean> </beans>
SqlMapClientDaoSupport
提供了類似 SqlMapDaoSupport
的功能。我們可以繼承它來實(shí)現(xiàn)我們自己的DAO:
public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao { public Account getAccount(String email) throws DataAccessException { return (Account) getSqlMapClientTemplate().queryForObject("getAccountByEmail", email); } public void insertAccount(Account account) throws DataAccessException { getSqlMapClientTemplate().update("insertAccount", account); } }
我們可以在application context中創(chuàng)建了 SqlMapAccountDao
并且注入 SqlMapClient
實(shí)例,這樣我們就可以在DAO中使用預(yù)先配置的
SqlMapClientTemplate
來執(zhí)行查詢了:
<beans> <bean id="accountDao" class="example.SqlMapAccountDao"> <property name="sqlMapClient" ref="sqlMapClient"/> </bean> </beans>
注意 SqlMapTemplate
實(shí)例也可以手工創(chuàng)建,使用
SqlMapClient
作為構(gòu)造函數(shù)參數(shù)。
SqlMapClientDaoSupport
基類為我們預(yù)先初始化了一個(gè)
SqlMapClientTemplate
實(shí)例。
SqlMapClientTemplate
還提供了一個(gè)通用的
execute
方法,將用戶自定義的 SqlMapClientCallback
的實(shí)現(xiàn)作為參數(shù)。舉例來說,這可以實(shí)現(xiàn)批量操作:
public class SqlMapAccountDao extends SqlMapClientDaoSupport implements AccountDao { public void insertAccount(Account account) throws DataAccessException { getSqlMapClientTemplate().execute(new SqlMapClientCallback() { public Object doInSqlMapClient(SqlMapExecutor executor) throws SQLException { executor.startBatch(); executor.update("insertAccount", account); executor.update("insertAddress", account.getAddress()); executor.executeBatch(); } }); } }
一般來說,任何由 SqlMapExecutor
API提供的操作組合都以這樣的回調(diào)形式被使用。
而在這個(gè)過程中產(chǎn)生的任何 SQLException
都將被自動(dòng)地轉(zhuǎn)化為Spring的通用的 DataAccessException
異常體系。
你也可以基于原生的iBATIS API來編程,而無(wú)需對(duì)Spring產(chǎn)生任何依賴。直接使用注入的
SqlMapClient
。一個(gè)相應(yīng)的DAO實(shí)現(xiàn)類看上去就像下面這樣:
public class SqlMapAccountDao implements AccountDao { private SqlMapClient sqlMapClient; public void setSqlMapClient(SqlMapClient sqlMapClient) { this.sqlMapClient = sqlMapClient; } public Account getAccount(String email) { try { return (Account) this.sqlMapClient.queryForObject("getAccountByEmail", email); } catch (SQLException ex) { throw new MyDaoException(ex); } } public void insertAccount(Account account) throws DataAccessException { try { this.sqlMapClient.update("insertAccount", account); } catch (SQLException ex) { throw new MyDaoException(ex); } } }
在這種情況下,由iBATIS API拋出的 SQLException
異常需要以
用戶自定義的方式進(jìn)行處理:通常封裝成為你的應(yīng)用程序自身的DAO異常。在application context
中進(jìn)行的整合看上去依然像以前一樣,這是由于基于原生的iBATIS的DAO依然遵循IoC的模式:
<beans> <bean id="accountDao" class="example.SqlMapAccountDao"> <property name="sqlMapClient" ref="sqlMapClient"/> </bean> </beans>