使用 ibatis 處理復(fù)雜對象數(shù)據(jù)關(guān)系的實例
上一篇 /下一篇 2010-09-07 16:18:20/ 個人分類:DB2
簡介: iBatis 是一個開源的對象關(guān)系映射程序,其工作是將對象映射到 SQL 語句。和其它 O/R Mapping 框架不同,iBatis 開發(fā)者需要自己編寫和維護(hù) SQL 語句,這給開發(fā)帶來了很多的靈活性的同時,也帶來了很大的復(fù)雜度與工作量。在一個數(shù)據(jù)庫中,常見的對象關(guān)系有:1 對 1,1 對多,多對多,單表映射,多表映射,單主鍵,多主鍵以及對象主鍵等種種情況。在使用 ibatis處理數(shù)據(jù)映射時,需要跟據(jù)不同的情況,寫出不同的 sql 語句和 sql map 的實現(xiàn),特別是在復(fù)雜關(guān)系跟復(fù)雜主鍵時需要編寫大量的復(fù)雜sql。本文將詳細(xì)介紹如何使用 ibatis來處理數(shù)據(jù)庫中的復(fù)雜數(shù)據(jù)對象關(guān)系,根據(jù)數(shù)據(jù)關(guān)系的分類,給出具體的實現(xiàn)代碼模板與解釋。通過本文讀者可以了解 ibatis處理復(fù)雜關(guān)系時可以使用方式,在具體編寫代碼過程中只需要套用本文中列出的這些模板,這樣可以大大簡化開發(fā)和加快開發(fā)的速度。本文的讀者需要對ibatis 已經(jīng)有一些基本的使用經(jīng)驗。
起源于 2001 年的開放源代碼項目 ibatis,是一個基于 Java的持久層框架。與 Hibernate, Toplink 等持久化框架不同,ibatis 是一個 “半自動化”的 ORM 實現(xiàn)。ibatis沒有對數(shù)據(jù)庫結(jié)構(gòu)提供了較為完整的封裝,而是提供了一個從 POJO 到數(shù)據(jù)庫表的全套映射機(jī)制。這使得在開發(fā) ibatis 的時候,需要手動的編寫sql 來提過數(shù)據(jù)庫與類對象之間的映射,這在給開發(fā)提供了很大的靈活性的同時,大大增加了開發(fā)的工作量。Ibatis 主要有以下的這些特性:
1. 簡單性
Ibatis是一個非常簡單易用的工具包。這個簡單性不僅僅體現(xiàn)在開發(fā)庫的輕量小巧上,iBATIS 對于 Java開發(fā)者來說也非常簡單。因為它除了不用編寫那么多代碼外與 JDBC 的工作機(jī)制非常相像,iBATIS 就是以 XML 的形式來描述的 JDBC代碼。iBATIS 對于數(shù)據(jù)庫管理員以及 SQL 程序員來 說也非常容易理解。iBATIS 配置文件幾乎人人都能讀懂,只要他有 SQL 編程的經(jīng)驗。
2. 效率與性能
iBATIS 通過一種簡單的方式來配置和使用,其性能與 JDBC 相當(dāng)。通過直接編寫 SQL 查詢,開發(fā)人員可以直接控制 SQL 語句來優(yōu)化執(zhí)行效率,甚至可以在其中調(diào)用存儲過程,為開發(fā)人員提供了巨大的 SQL 優(yōu)化空間。
3. 代碼分離
在iBATIS 中,SQL 語句在很大程度上同應(yīng)用的源代碼是分離 的,SQL 程序員可以按照 SQL 原本的方式來編寫它,而不必?fù)?dān)心有關(guān) SQL字符串連接的問題。iBATIS 提供了充分的自由,使得任何人都可以開發(fā)、觀察并且修改在數(shù)據(jù)庫中執(zhí)行的 SQL 語句。
4. 可移植性
iBATIS 是可移植的。由于它相對簡單的設(shè)計,它幾乎可以用任何一種語言在任何一個平臺上實現(xiàn)。iBATIS 支持 3 種最受歡迎的開發(fā)平臺:Java、Ruby 和微軟 .NET 的 C#。
由于在使用 ibatis 進(jìn)行項目開發(fā)中,需要根據(jù)數(shù)據(jù)庫的表結(jié)構(gòu)與 Java 類之間的關(guān)系寫出實現(xiàn)的 SQL 代碼,不同的關(guān)系會對應(yīng)不同 SQL實現(xiàn)。這些 SQL 代碼將會和其他 mapping 信息一起放在 ibatis 的 SQL mapping文件中。下面就對這些每一種映射進(jìn)行詳細(xì)分析并給出實現(xiàn)示例。
在 ibatis 中最簡單的關(guān)系就是一個對象對單個表的綁定,這也是最簡單的類與數(shù)據(jù)庫的映射關(guān)系。在沒有任何外鍵關(guān)系的時候,在 ibatis 中直接將類的字段對應(yīng)到表的列即可:
清單 1. 單個對象表綁定的實現(xiàn)
<typeAlias alias="Bank" type="com.example.domain.Bank"/> <resultMap id="getBankResult" class="Bank"> <result property="id" column="B_ID"/> <result property="name" column="B_NAME"/> </resultMap> <select id="getBankById" resultMap="getBankResult" parameterClass="string"/> SELECT `BANKL`.`BANKID` AS `B_ID`, `BANKL`.`NAME` AS `B_NAME` FROM `BANKL` WHERE `BANKID` = #id# </select/> |
在某些特殊的對象中,有的時候需要將一個對象映射到多個表中,在這個時候就需要在映射時加入對兩張表的選擇。因此,需要對上面的簡單的 sql 進(jìn)行一些改動,加入一個兩張表的 join 操作,以下是示例:
清單 2. 單個對象多表綁定的實現(xiàn)
<typeAlias alias="Customer" type="com.example.domain.Customer"/> <resultMap id="getCustomerResult" class="Customer"> <result property="id" column="C_ID"/> <result property="name" column="C_NAME"/> <result property="birthday" column="C_BIRTHDAY"/> <result property="gender" column="C_GENDER"/> <result property="identityType" column="C_IDENTITYTYPE"/> <result property="identityId" column="C_IDENTITYID"/> <result property="consumePoint" column="C_CONSUMEPOINT"/> <result property="lastGetDate" column="C_LASTGETDATE"/> <result property="lastUseDate" column="C_LASTUSEDATE"/> </resultMap> <select id="getCustomerById" resultMap="getCustomerResult" parameterClass="string"/> SELECT `CUMAS`.`ID` AS `C_ID`, `CUMAS`.`NAME` AS `C_NAME`, `CUMAS`.`BIRTHDAY` AS `C_BIRTHDAY`, `CUMAS`.`GENDER` AS `C_GENDER`, `CUMAS`.`IDTYPE` AS `C_IDENTITYTYPE`, `CUMAS`.`IDNO` AS `C_IDENTITYID`, `CUSPT`.`POINT` AS `C_CONSUMEPOINT`, `CUSPT`.`LASTGET` AS `C_LASTGETDATE`, `CUSPT`.`LASTUSE` AS `C_LASTUSEDATE` FROM `CUMAS`, `CUSPT` WHERE`ID` = #id# AND `CUMAS`.`ID` = `CUSPT`.`CUSID`<select/> |
在上面這個例子中,Customer 這個對象被映射到 CUMAS 與 CUSPT 兩個表中,每個表中包含了一部分字段,所以在選擇的時候需要將兩張表join 起來。在進(jìn)行刪除,修改等操作時,需要注意的是要創(chuàng)建兩條語句并在 java code中對兩條語句都進(jìn)行調(diào)用,否則會導(dǎo)致數(shù)據(jù)不一致的現(xiàn)象發(fā)生:
清單 3. 單個對象多表綁定的刪除語句
<delete id="deleteCustomer" parameterClass="string"> DELETE FROM `CUMAS` WHERE `ID` = #id# </delete> <delete id="deleteCustomer2" parameterClass="string"> DELETE FROM `CUSPT` WHERE `CUSID` = #id# </delete> |
在數(shù)據(jù)庫中,一般需要對每條記錄定義一個主鍵,大部分情況下采用一個自增長的 ID 來實現(xiàn)。這個時候有兩種實現(xiàn)方法,第一種是用數(shù)據(jù)庫自帶的 id增長功能,如何在 ibatis 中實現(xiàn)這種情況已在 iBatis 幫助文檔中有詳細(xì)說明,這里就不在贅述。第二種方法是采用類似 Toplink中的實現(xiàn)方式,在 Java 中控制 ID 的增長,這種方法使用一張 sequence 表來存放所有的 id記錄,該表有兩個字段,第一個為表名,第二個為當(dāng)前最新的 id 值,表中的每一行對應(yīng)一個自增長的 id。與該表對應(yīng)的為一個 Java 的Sequence 類與 iBatis 映射文件。在查詢每個 sequence 時,通過 sequence name 將當(dāng)前 id值取出并設(shè)置到對象的 id 中。
在獲取新的 sequence 時,需要注意的是對并發(fā)的控制,在同一時間只能有一個線程更新 sequence,否則將會導(dǎo)致主鍵重復(fù)。
清單 4. Sequence 的實現(xiàn)
Sequence 的 Java 類public class Sequence{ protected String name; protected String nextId; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getNextId() { return nextId; } public void setNextId(String nextId) { this.nextId = nextId; } }Sequence 的 SQL 映射<sqlMap namespace="Sequence"> <typeAlias alias="Sequence" type="com.example.Sequence"/> <resultMap id="getSequenceResult" class="Sequence"> <result property="name" column="S_NAME"/> <result property="nextId" column="S_NEXTID"/> </resultMap> <select id="getSequenceById" resultMap="getSequenceResult" parameterClass="string" > SELECT `SEQ`.`SEQNAME` AS `S_NAME`, `SEQ`.`SEQVALUE` AS `S_NEXTID` FROM `SEQ` WHERE `SEQNAME` = #name# </select> <update id="updateSequence" parameterClass="Sequence"> UPDATE `B2CSEQ` SET `SEQVALUE`=#nextId# WHERE `SEQNAME` = #name# </update> </sqlMap>通過 Sequence 獲取 ID 的方法public static synchronized String getNextId(String name) throws SQLException { SqlMapSession sequenceSession=SessionManager.retrieveSession(); ISequence sequence = (ISequence) sequenceSession.queryForObject( "getSequenceById", name); if (sequence == null) { throw new SQLException("Error: A null sequence was returned from the database" + " (could not get next "+ name + " sequence)."); } String id = sequence.getNextId(); sequence.setNextId((new BigDecimal(id).add(new BigDecimal(5))).toString()); sequenceSession.startTransaction(); sequenceSession.update("updateSequence", sequence); sequenceSession.commitTransaction(); sequenceSession.close(); return String.valueOf(sequence.getNextId()); } |
對于類與類之間的引用關(guān)系,最常見的是一對一,一對多與多對多。下面就講述對這三種關(guān)系的實現(xiàn)。
在類與類之間關(guān)系中,一對一是最簡單的一種。在每個類中有一個對其他類的引用,反之亦然。此時只需在 ibatis 的 result map 中建立對對象的引用關(guān)系即可:
清單 5. 一對一的引用
<result property="belongedCatalog" column="A_BELONGEDCATALOG" select="getArticleCatalogById"/> |
在上面的 mapping 中,A_BELONGEDCATALOG 為查詢結(jié)果中的一個字段,而 getArticleCatalogById為一個返回結(jié)果為 Catalog 的查詢。因此 ibatis 在調(diào)用時,將會把 A_BELONGEDCATALOG 作為參數(shù)傳入getArticleCatalogById 來生成一個 Catalog 實例的引用 , 并將改引用賦值給 belongedCatalog 屬性。
一對多關(guān)系與 1 對 1 關(guān)系的區(qū)別之處在于類中引用的對象為一個列表而非單個對象,因此在 resultmap 中的 mapping是一樣的,唯一的區(qū)別在于關(guān)聯(lián)的 select 返回的為一個列表而非單個對象(上例中的 getArticleCatalogById的返回結(jié)果為一個對象,而對于一對多關(guān)系此方法將返回一個列表)。因此在這里不再給出實現(xiàn)。
在實現(xiàn)多對多關(guān)系時,每個類都可能包含多個對對方類的引用列表,通常需要建立一張關(guān)系表用來存儲關(guān)系映射,如下所示:
清單 6. 多對多的關(guān)系表
CREATE TABLE `ARTICLE_GROUP_RELATION` ( `GROUPID` varchar(10) not null , `ARTICLEID` varchar(10) not null ); |
在這里 Article 與 Group 兩個對象之間存在多對多關(guān)系,GROUPID 與 ARTICLEID 字段分別對應(yīng)與 Group 表與Article 表的主鍵。若在 Group 對象中有一個對 Article 列表的引用,首先需要在 Group 的 resultmap中定義一個 List 的屬性。這個屬性會映射到一條根據(jù) GroupID 查出 Article 的語句getArticleByArticleGroupId,該查詢需要將上面定義的關(guān)系表與 Article 表進(jìn)行連接,返回結(jié)果為一個 Article的列表 :
清單 7. 多對多的關(guān)系映射
<result property="articleList" column="AG_ID" select="getArticleByArticleGroupId"/> <select id="getArticleByArticleGroupId" resultMap="getArticleResult" parameterClass="string"> SELECT `ARTICLE`.`ID` AS `A_ID`, `ARTICLE`.`NAME` AS `A_NAME`, `ARTICLE`.`INDUSTRY` AS `A_ISINDUSTRY`, `ARTICLE`.`UPDATEDATE` AS `A_UPDATEDATE` FROM ` ARTICLE `, ` ARTICLE_GROUP_RELATION ` WHERE `ARTICLE_GROUP_RELATION`.`GROUPID` = #id# AND `ARTICLE_GROUP_RELATION`.`ARTICLEID` = `ARTICLE`.`ID` </select> |
需要注意的是,在對應(yīng)的增加 / 刪除 / 修改操作中,也需要調(diào)用一個 SQL 語句來更新關(guān)系表,否則會導(dǎo)致表中的數(shù)據(jù)不一致,以刪除為例:
清單 8. 多對多的刪除語句
<delete id="deleteArticleGroupArticleList" parameterClass="string" > DELETE FROM `ARTICLE_GROUP_RELATION` WHERE `GROUPID` = #id# </delete> |
上一章介紹了類之間的關(guān)系的實現(xiàn),本章在上一章的基礎(chǔ)上,介紹了幾種對象主鍵與繼承類關(guān)系的實現(xiàn)。
對象主鍵是一種非常特殊的主鍵實現(xiàn),此時不是使用一個自動增長的 ID作為類的主鍵,而是將類中所引用到的某個對象作為主鍵。因此,在建表的時候就需要將主鍵對象表中的主鍵字段作為該表中的主鍵字段保存,同樣在進(jìn)行resultmap 的定義時需要建立一個對與其他對象的引用:
在下面這個例子中,UserCredit 對象中包含一個createUser 對象并以該對象作為主鍵,而 User 對象本身包含了兩個主鍵:用戶 ID 與注冊系統(tǒng)。因此在對 UserCredit建表時將 USERID 跟 REGISTEREDSYSTEM 作為兩個字段存放,對應(yīng)的在映射時需要將這兩個字段一起映射到 user對象的查詢上。對應(yīng)的字段映射與查詢語句如下:
清單 9. 對象主鍵的關(guān)系映射
<result property="createUser" column="userId= USERID , registeredSystem= REGISTEREDSYSTEM" select="getUserById"/> <select id="getUserById" resultMap="getUserResult" parameterClass="java.util.HashMap" > SELECT `SYUSR`.`USERID` AS `U_USERID`, `SYUSR`.`SYSCODE` AS `U_REGISTEREDSYSTEM`, `SYUSR`.`NAME` AS `U_NAME`, `SYUSR`.`SYSNAME` AS `U_DISPNAME`, `SYUSR`.`GENDER` AS `U_GENDER`, `SYUSR`.`MOBILE` AS `U_MOBILE`, `SYUSR`.`EMAIL` AS `U_EMAIL FROM `SYUSR` WHERE `USERID` = #userId# AND `SYSCODE` = #registeredSystem# </select> <select id="getUserCreditByUser" resultMap="getUserCreditResult" parameterClass="java.util.HashMap"> SELECT `NUMBER`, `NUMBERREMAIN`, ` USERID `, `SYSCODE` FROM `CREDIT` WHERE `CREDIT`.` USERID ` = #userId# AND `CREDIT`.`SYSCODE` = #registeredSystem# </select> |
需要注意的是,在getUserById 中接受的參數(shù)為一個 HahsMap,這個 HashMap 中存放了兩個字段:userId 和registeredSystem。因此在映射是需要寫成 column="userId= USERID , registeredSystem=REGISTEREDSYSTEM"的方式來傳入一個 Map 參數(shù)。
對于對象主鍵的查詢語句,可以將參數(shù)設(shè)為一個對象,也可以將參數(shù)設(shè)為一個 Map,在 Map 中放入 userId 與 registeredSystem,在查詢時使用這兩個值作為查詢條件。類似的在其他增加 /刪除 / 修改操作時也可以傳入一個 HashMap 作為參數(shù)。
在上一小節(jié)的基礎(chǔ)上,如果某個以對象為主鍵的類被其他類所引用并建立了一對多或者多對多的關(guān)系,此時在 mapping 時需要把前一章中使用的關(guān)聯(lián)的 id 改成對象的主鍵。下面是一對多的示例,首先在 resultmap 中定義屬性映射,然后定義了對應(yīng)的查詢方法。
清單 10. 一對多對象主鍵的關(guān)系映射
<result property="groupList" column="userId= USERID , registeredSystem= REGISTEREDSYSTEM" select=" getAttrListByUser "/> <select id="getAttrListByUser" resultMap="getAttrResult" parameterClass="java.util.HashMap"> SELECT `ATTRIBUTENAME`, `ATTRIBUTEVALUE`, ` USERID `, `SYSCODE` FROM `ATTRIBUTE` WHERE `ATTRIBUTE`.`USERID` = #userId# AND `ATTRIBUTE`.`SYSCODE` = #registeredSystem# </select> |
將上面的對象主鍵與前面提到的多對多關(guān)系結(jié)合起來,可以得到最復(fù)雜的多對多的對象主鍵的實現(xiàn)。首先在關(guān)系表中需要加入對于對象主鍵的定義。假設(shè) Article 對象為多主鍵對象,在Article 中有一個 GroupList 的屬性,Article 與 Group 有多對多的關(guān)系,以下為表的定義與 resultmap的實現(xiàn):
清單 11. 一對多對象主鍵的關(guān)系映射
CREATE TABLE `ARTICLE_GROUP_RELATION` ( `GROUPID` varchar(10) not null , `ARTICLETITLE` varchar(10) not null, `ARTICLEUSER` varchar(10) not null ); <result property="groupList" column=" articleTitle=TITLE, articleUser=USERID" select="getGroupByArticle"/> <select id="getGroupByArticle" resultMap="getGroupResult" parameterClass="java.util.HashMap"> SELECT `GROUP`.`NAME` AS `G_NAME`, `GROUP`.`ID` AS `G_ID` FROM ` GROUP `, ` ARTICLE_GROUP_RELATION ` WHERE `ARTICLE_GROUP_RELATION`.`GROUPID` = GROUP.`ID` AND `ARTICLE_GROUP_RELATION`.`ARTICLETITLE` = #articleTitle# AND `ARTICLE_GROUP_RELATION`.`ARTICLEUSER` = #articleUser# </select> <delete id="deleteArticleGroupArticleList" parameterClass="java.util.HashMap" > DELETE FROM `ARTICLE_GROUP_RELATION` WHERE `GROUPID` = #groupId# AND `ARTICLE_GROUP_RELATION`.`ARTICLETITLE` = #articleTitle# AND `ARTICLE_GROUP_RELATION`.`ARTICLEUSER` = #articleUser# </delete> |
上面的getGroupByArticle 為一條根據(jù) Article 查出 Group 的語句,該查詢需要將關(guān)系表與 Groupe 表join,返回結(jié)果為一個 Group 的列表。同樣需要注意的是,在對應(yīng)的增加 / 刪除 / 修改操作中,也需要調(diào)用一個 SQL語句來更新關(guān)系表,上面是刪除的例子。
類的繼承關(guān)系是一種非常常見的類關(guān)系,在一般的應(yīng)用中都會涉及。一般會將一些公有的屬性與方法放在一個父類中,然后不同的子類繼承父類。在進(jìn)行數(shù)據(jù)庫的映射時,對于繼承關(guān)系可以有兩種處理方法。第一種是對于父類并不單獨建表與之對應(yīng),而是分別對每個子類分別建表與做映射,所有父類的屬性都在子類中保存有一份。這種方法的好處是在進(jìn)行映射時非常簡單,與一般類的處理相同,壞處是是并利用類的繼承的特點,子類的表中會有大量重復(fù)的屬性。第二種方法是對于父類建立一張表與之對應(yīng),對于每一個子類也單獨建立一張表與之對應(yīng),但是在子類當(dāng)中并不保存父類的屬性,父類的屬性只保存在父類的表當(dāng)中。對于所有的父類與子類,都采用一套相同的 id,這就是說如果子類的表中有一行 ID 值為 10 的數(shù)據(jù),在父類表中也會有一行 ID 值為 10的數(shù)據(jù)。這兩行數(shù)據(jù)分別存放子類與父類中的屬性值。為了區(qū)分具體的值是屬于哪個子類,在父類中需要定義一個特殊字段CLASSKEY,這個字段的值表示該行是屬于哪個字段。這種方法也是在很多 O/R mapping工具中常用的方法,下面將詳細(xì)講述這種方法的實現(xiàn)。在下面的這里實現(xiàn)示例中有三個類:Customer(客戶),ComanyCustomer(公司客戶), PersonCustomer(個人客戶)。 Customer 為一個父類,ComanyCustomer 與 PersonCustomer繼承了 Customer。在數(shù)據(jù)庫中對應(yīng)的有三張表 CUSTOMER, COMPANYCUSTOMER 和 PERSONCUSTOMER。在下面的實現(xiàn)中,“COM”為 ComanyCustome 類所對應(yīng)的 Class Keyr,“PERSON”為 PersonCustomer對應(yīng)的 Class Key。在進(jìn)行查詢的時候需要將子表與父表相 join,在進(jìn)行增加 / 刪除 /修改操作的時候,也需要同時更改父類表與子類表,如增加中需要同時調(diào)用下面的兩條增加語句。
清單 12. 繼承關(guān)系的實現(xiàn)
<select id="getCompanyCustomerByID" resultMap="getCompanyCustomerResult" parameterClass="string"> SELECT `CUSTOMER`.`NAME` AS `C_NAME`, `COMPANYCUSTOMER`.`ID` AS `C_ID`, `COMPANYCUSTOMER`.`LICENSE` AS `C_ LICENSE` FROM `COMPANYCUSTOMER`, `CUSTOMER` WHERE `COMPANYCUSTOMER`.`ID` = `CUSTOMER`.`ID` AND `CUSTOMER`.`CLASSKEY` = ‘ COM ’ AND `COMPANYCUSTOMER`.`ID` = #id# </select> <insert id="insertCustomer" parameterClass="Customer"> INSERT INTO `CUSTOMER` (`CUSTOMER`.`ID`, `CUSTOMER`.`CLASSKEY`, `CUSTOMER`.` NAME `) VALUES ( #id#, #classKey#,#name#) </insert> <insert id="insertComanyCustomer" parameterClass="ComanyCustomer"> INSERT INTO `COMPANYCUSTOMER` (`COMPANYCUSTOMER`.`ID`, `COMPANYCUSTOMER`.` NAME `) VALUES ( #id#, #license#) </insert> <select id="getClassKeyByID" resultClass="string” parameterClass="string"> SELECT `CUSTOMER`.` CLASSKEY` AS `C_ CLASSKEY` FROM `CUSTOMER` WHERE `CUSTOMER`.`ID` = #id# </select> |
繼承關(guān)系比其他關(guān)系復(fù)雜的實現(xiàn)是在java 類也需要做一些特殊的處理,在引用 Customer 類的時候,可以直接引用父類或子類。引用父類時可能指向的是一個ComanyCustomer 的實例,也可能是一個 PersonalCustomer 的實例。然而在僅僅知道 id的時候無法判斷是哪一個具體的子類,在這個時候,就需要根據(jù) ClassKey 來判讀具體是哪一個實例了。首先需要有一個方法獲取ClassKey,然后根據(jù) ClassKey 來調(diào)用獲取具體子類的語句。
清單 13. 繼承關(guān)系的 Java 實現(xiàn)
public Customer getCustomerById(String id) { String classKey=(String) sqlSession.queryForObject("getClassKeyByID", id); if(“COM”.equals(classKey)) return (Customer) sqlSession.queryForObject("getCompanyCustomerByID", id); else if(“PERSON”.equals(classKey)) return (Customer) sqlSession.queryForObject("getPersonCustomerByID", id); } |
本文介紹了關(guān)于 iBatis 開發(fā)中常用的映射的實現(xiàn),由于 iBatis 的所有語句必須靠開發(fā)人員生成,上面描述的種種對象關(guān)系和給出的實現(xiàn)實例將對開發(fā) iBatis 的應(yīng)用具有非常大的指導(dǎo)意義。
原文鏈接:http://www.ibm.com/developerworks/cn/opensource/os-cn-ibatis/index.html