前段時(shí)間寫(xiě)了些 Hibernate 方面的系列文章,網(wǎng)友們反映還不錯(cuò)。在接下來(lái)的時(shí)間里,我將會(huì)引入另外一種 O/R Mapping 解決方案——iBATIS,本系列將沿用 Hibernate 系列文章的風(fēng)格。
什么是 iBATIS ?
和眾多的 SourceForge 開(kāi)源項(xiàng)目一樣,iBATIS 曾經(jīng)也是其中的一員。在2004年11月3日成功地成為了 Apache Incubator 下的子項(xiàng)目。 iBATIS 包括 for Java 和 for .NET 兩個(gè)版本,for Java 版提供了SQL Maps 和 DAO 框架,for .NET 只提供了 SQL Maps 框架。從現(xiàn)在開(kāi)始我們只對(duì) for Java 版的SQL Maps 展開(kāi)討論。
你可以在 http://www.ibatis.com 下載 iBATIS for Java,目前最新版本是2.0.9,壓縮包里已經(jīng)包含了 SQL Maps(ibatis-sqlmap-2.jar) 和 DAO 框架(ibatis-dao-2.jar)。
為什么選擇 iBATIS ?
也許各位看官已在各種不同的技術(shù)資料上了解到它的優(yōu)勢(shì)。但是對(duì)于我來(lái)說(shuō),選擇它的理由只有一個(gè)——“利用原有資源”。Hibernate 的卻優(yōu)秀,但是用來(lái)整合原有系統(tǒng),它卻很難勝任。例如,以前在進(jìn)行數(shù)據(jù)建模時(shí)使用了復(fù)合主鍵、跨越多表產(chǎn)生的幾十甚至上百行的查詢語(yǔ)句、利用原有存儲(chǔ)過(guò)程… … 當(dāng)面臨這一系列問(wèn)題時(shí) Hibernate 就顯得力不從心了,要想使用 Hibernate就只能改造原有系統(tǒng)!
當(dāng)我面臨系統(tǒng)整合問(wèn)題時(shí)(整合的要求很簡(jiǎn)單:只需要保留原有系統(tǒng)查詢部分),iBATIS 進(jìn)入了我的視線。原有系統(tǒng)中除 SQL語(yǔ)句需要小小的修改外,數(shù)據(jù)表、查詢結(jié)果都不需要改變!也不用像 Hibernate 那樣映射出眾多的配置文件、POJO,一下子清爽了很多。BTW:Hibernate 這種做法沒(méi)有錯(cuò)!只是我只需要查詢功能,僅僅是取我所好而已,避免了殺雞用牛刀。
目前,系統(tǒng)整合已經(jīng)結(jié)束,花了一個(gè)月時(shí)間。如果使用 Hibernate,恐怕我現(xiàn)在還在為怎么設(shè)計(jì)數(shù)據(jù)表、怎樣下HQL而和同事?tīng)?zhēng)論。
開(kāi)始另一次 O/R Mapping 之旅
上次 O/R Mapping 之旅的 BO、數(shù)據(jù)表還可以重用,只是把數(shù)據(jù)庫(kù)遷移到了 MySQL。打開(kāi) Eclipse,新建一個(gè) Resin 項(xiàng)目。把 ibatis-sqlmap-2.jar 和 ibatis-common-2.jar 拷貝到 lib 目錄下,再導(dǎo)入項(xiàng)目。和 Hibernate 自動(dòng)配置、自動(dòng)映射相比,iBATIS 的一切都是手工完成的。
在 src 下建立配置文件 SqlMapConfig.xml,數(shù)據(jù)庫(kù)鏈接、連接池、SqlMap 映射文件… … 這些都要靠它了。官方參考手冊(cè)對(duì)怎樣進(jìn)行設(shè)置有很詳細(xì)的描述,我只對(duì)要用到的地方進(jìn)行粗略說(shuō)明。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE sqlMapConfig PUBLIC "-//iBATIS.com//DTD SQL Map Config 2.0//EN" "http://www.ibatis.com/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings cacheModelsEnabled="true" enhancementEnabled="true" lazyLoadingEnabled="true" errorTracingEnabled="false" maxRequests="32" maxSessions="10" maxTransactions="5" useStatementNamespaces="false" />
<transactionManager type="JDBC"> <dataSource type="SIMPLE"> <property name="JDBC.Driver" value="org.gjt.mm.mysql.Driver"/> <property name="JDBC.ConnectionURL" value="jdbc:mysql://localhost/new_db?useUnicode=true"/> <property name="JDBC.Username" value="root"/> <property name="JDBC.Password" value=""/> <property name="JDBC.DefaultAutoCommit" value="true"/> <property name="Pool.MaximumActiveConnections" value="10"/> <property name="Pool.MaximumIdleConnections" value="5"/> <property name="Pool.MaximumCheckoutTime" value="120000"/> <property name="Pool.TimeToWait" value="500"/> <property name="Pool.PingQuery" value="select 1 from ACCOUNT"/> <property name="Pool.PingEnabled" value="false"/> <property name="Pool.PingConnectionsOlderThan" value="1"/> <property name="Pool.PingConnectionsNotUsedFor" value="1"/> <property name="Pool.QuietMode" value="true"/> </dataSource> </transactionManager>
<sqlMap resource="bo/mapping/AutoMag.xml"/> </sqlMapConfig> |
transactionManager 元素定義了 iBATIS 事務(wù)管理器。type 可選項(xiàng)包括:
JDBC:通過(guò)傳統(tǒng) JDBC 來(lái)管理事務(wù)。
JTA:使用一個(gè) JTA 全局事務(wù),使 iBATIS 的事務(wù)包括在更大的事務(wù)范圍內(nèi)(跨數(shù)據(jù)庫(kù)Session的),這個(gè)更大的事務(wù)范圍可能包括了其他的數(shù)據(jù)庫(kù)和事務(wù)資源。這個(gè)配置需要一個(gè) UserTransaction 屬性,以便從 JNDI 獲得一個(gè) UserTransaction。
EXTERNAL:調(diào)用 iBATIS 以外的其他事務(wù)管理器來(lái)管理事務(wù)。
dataSource 元素是 transactionManager 的一部分。type 可選項(xiàng)包括:
SIMPLE:SIMPLE 是 iBATIS 內(nèi)置的 dataSource 實(shí)現(xiàn),其中實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的數(shù)據(jù)庫(kù)連接池,當(dāng)無(wú)容器提供 DataSource 服務(wù)時(shí)可以使用該選項(xiàng),對(duì)應(yīng) iBATIS 實(shí)現(xiàn)類為com.ibatis.sqlmap.engine.datasource.SimpleDataSourceFactory。
? DBCP:基于 Apache DBCP 連接池 API 實(shí)現(xiàn)的 DataSource,當(dāng)無(wú)容器提供 DataSource 服務(wù)時(shí),可以使用該選項(xiàng),對(duì)應(yīng) iBATIS 實(shí)現(xiàn)類為 com.ibatis.sqlmap.engine.datasource.DbcpDataSourceFactory。
?JNDI:使用 J2EE 容器提供的 DataSource 實(shí)現(xiàn),DataSource 將通過(guò)指定的 JNDI Name 從容器中獲取。對(duì)應(yīng) iBATIS 實(shí)現(xiàn)類為 com.ibatis.sqlmap.engine.datasource.JndiDataSourceFactory。
注意!每種 dataSource 元素的 property 都有不同的地方,不能光把 type 名字改了了事。
sqlMap 元素定義了映射文件的存放位置,配置文件中可包含多個(gè) sqlMap 元素,比如:
你也許已發(fā)現(xiàn),我只定義了單個(gè)映射文件。不錯(cuò),和 Hibernate 的一個(gè)表一個(gè)映射文件不同,iBATIS 的映射文件個(gè)數(shù)可以人為控制,顆粒度自己掌握。
光有 BO 和配置文件還不行,還要為本次測(cè)試創(chuàng)建測(cè)試類 AutoMag.java。完整的布局如下所示:

以下為 iBATIS SQL Maps 工作流程,對(duì)于理解概念很有幫助。大意是 1、你可以把 JavaBean、Map 類型、原始變量(或者它們的Wrapper Class)、XML 數(shù)據(jù)作為傳入對(duì)象;2、通過(guò)配置文件載入映射文件;3、利用框架翻譯成 JDBC 來(lái)訪問(wèn)數(shù)據(jù)庫(kù);4、執(zhí)行結(jié)果可以是 JavaBean、Map 類型、原始變量(或者它們的Wrapper Class)、XML 數(shù)據(jù)。

(請(qǐng)注意!引用、轉(zhuǎn)貼本文應(yīng)注明原作者:Rosen Jiang 以及出處:http://blog.csdn.net/rosen)