鳳凰涅槃:從iBatis到MyBatis-創(chuàng)新互聯(lián)

從 iBatis 到 MyBatis,你準(zhǔn)備好了嗎?

對(duì)于從事 Java EE 的開發(fā)人員來說,iBatis 是一個(gè)再熟悉不過的持久層框架了,在 Hibernate、JPA 這樣的一站式對(duì)象 / 關(guān)系映射(O/R Mapping)解決方案盛行之前,iBaits 基本是持久層框架的不二選擇。即使在持久層框架層出不窮的今天,iBatis 憑借著易學(xué)易用、輕巧靈活等特點(diǎn),也仍然擁有一席之地。尤其對(duì)于擅長 SQL 的開發(fā)人員來說,iBatis 對(duì) SQL 和存儲(chǔ)過程的直接支持能夠讓他們?cè)讷@得 iBatis 封裝優(yōu)勢(shì)的同時(shí)而不喪失 SQL 調(diào)優(yōu)的手段,這是 Hibernate/JPA 所無法比擬的。具體而言,使用 iBatis 框架的主要優(yōu)勢(shì)主要體現(xiàn)在如下幾個(gè)方面:

成都一家集口碑和實(shí)力的網(wǎng)站建設(shè)服務(wù)商,擁有專業(yè)的企業(yè)建站團(tuán)隊(duì)和靠譜的建站技術(shù),十載企業(yè)及個(gè)人網(wǎng)站建設(shè)經(jīng)驗(yàn) ,為成都超過千家客戶提供網(wǎng)頁設(shè)計(jì)制作,網(wǎng)站開發(fā),企業(yè)網(wǎng)站制作建設(shè)等服務(wù),包括成都營銷型網(wǎng)站建設(shè),成都品牌網(wǎng)站建設(shè),同時(shí)也為不同行業(yè)的客戶提供做網(wǎng)站、網(wǎng)站設(shè)計(jì)的服務(wù),包括成都電商型網(wǎng)站制作建設(shè),裝修行業(yè)網(wǎng)站制作建設(shè),傳統(tǒng)機(jī)械行業(yè)網(wǎng)站建設(shè),傳統(tǒng)農(nóng)業(yè)行業(yè)網(wǎng)站制作建設(shè)。在成都做網(wǎng)站,選網(wǎng)站制作建設(shè)服務(wù)商就選成都創(chuàng)新互聯(lián)公司。

首先,iBatis 封裝了絕大多數(shù)的 JDBC 樣板代碼,使得開發(fā)者只需關(guān)注 SQL 本身,而不需要花費(fèi)精力去處理例如注冊(cè)驅(qū)動(dòng),創(chuàng)建 Connection,以及確保關(guān)閉 Connection 這樣繁雜的代碼。

其次,iBatis 可以算是在所有主流的持久層框架中學(xué)習(xí)成本最低,最容易上手和掌握的框架。雖說其他持久層框架也號(hào)稱門檻低,容易上手,但是等到你真正使用時(shí)會(huì)發(fā)現(xiàn),要想掌握并用好它是一件非常困難的事。在工作中我需要經(jīng)常參與面試,我曾聽到過很多位應(yīng)聘者描述,他們所在的項(xiàng)目在技術(shù)選型時(shí)選擇 Hibernate,后來發(fā)現(xiàn)難以駕馭,不得不將代碼用 JDBC 或者 iBatis 改寫。

iBatis 自從在 Apache 軟件基金會(huì)網(wǎng)站上發(fā)布至今,和他的明星兄弟們(Http Server,Tomcat,Struts,Maven,Ant 等等)一起接受者萬千 Java 開發(fā)者的敬仰。然而在今年六月中旬,幾乎是發(fā)布 3.0 版本的同時(shí),iBatis 主頁上的一則 “Apache iBATIS has been retired” 的聲明在社區(qū)引起了一陣不小的波瀾。在 Apache 寄居六年之后,iBatis 將代碼托管到 Google Code。在聲明中給出的主要理由是,和 Apache 相比,Google Code 更有利于開發(fā)者的協(xié)同工作,也更能適應(yīng)快速發(fā)布。于此同時(shí),iBatis 更名為 MyBatis。

從 iBatis 到 MyBatis,不只是名稱上的變化,MyBatis 提供了更為強(qiáng)大的功能,同時(shí)并沒有損失其易用性,相反,在很多地方都借助于 JDK 的泛型和注解特性進(jìn)行了簡化。iBatis 確實(shí)該退休了,因?yàn)橐粋€(gè)更為出色的繼任者經(jīng)過 10 個(gè) Beta 版本的蛻變已然出現(xiàn)在我們的面前。

本文將主要針對(duì) MyBatis 和 iBatis 的變化之處進(jìn)行討論,以便于讀者順利從 iBatis 向 MyBatis 過渡。

由一個(gè) MyBatis 示例開始

如果讀者接觸過一些常用的 Java EE 框架,應(yīng)該都知道這些框架需要提供一個(gè)全局配置文件,用于指定程序正常運(yùn)行所需的設(shè)置和參數(shù)信息。而針對(duì)常用的持久層框架而言(Hibernate、JPA、iBatis 等),則通常需要配置兩類文件:一類用于指定數(shù)據(jù)源、事務(wù)屬性以及其他一些參數(shù)配置信息(通常是一個(gè)獨(dú)立的文件,可以稱之為全局配置文件);另一類則用于指定數(shù)據(jù)庫表和程序之間的映射信息(可能不止一個(gè)文件,我們稱之為映射文件)。MyBatis 也不例外,雖然其中的一部分可以通過注解的形式進(jìn)行,但是這兩部分內(nèi)容本身仍是必不可少的。

根據(jù) iBatis 的習(xí)慣,我們通常把全局配置文件命名為 sqlMapConfig.xml,文件名本身并沒有要求,在 MyBatis 中,也經(jīng)常會(huì)將該文件命名為 Configuration.xml (讀完全文后讀者也許會(huì)發(fā)現(xiàn),在 iBatis 中經(jīng)常出現(xiàn)的 “sqlMap” 在 MyBatis 中被逐漸淡化了,除了此處,還比如 iBatis 配置文件的根元素為 <sqlMapConfig>,指定映射文件的元素為 <sqlMap>,以及 SqlMapClient 等等,這個(gè)變化正說明,iBatis 僅是以 SQL 映射為核心的框架,而在 MyBatis 中多以 Mapper、Session、Configuration 等其他常用 ORM 框架中的名字代替,體現(xiàn)的無非是兩個(gè)方面:首先是為了減少開發(fā)者在切換框架所帶來的學(xué)習(xí)成本;其次,MyBatis 充分吸收了其他 ORM 框架好的實(shí)踐,MyBatis 現(xiàn)在已不僅僅是一個(gè) SQL 映射框架了)。在全局配置文件中可以配置的信息主要包括如下幾個(gè)方面:

  • properties --- 用于提供一系列的鍵值對(duì)組成的屬性信息,該屬性信息可以用于整個(gè)配置文件中。

  • settings --- 用于設(shè)置 MyBatis 的運(yùn)行時(shí)方式,比如是否啟用延遲加載等。

  • typeAliases --- 為 Java 類型指定別名,可以在 XML 文件中用別名取代 Java 類的全限定名。

  • typeHandlers --- 在 MyBatis 通過 PreparedStatement 為占位符設(shè)置值,或者從 ResultSet 取出值時(shí),特定類型的類型處理器會(huì)被執(zhí)行。

  • objectFactory --- MyBatis 通過 ObjectFactory 來創(chuàng)建結(jié)果對(duì)象??梢酝ㄟ^繼承 DefaultObjectFactory 來實(shí)現(xiàn)自己的 ObjectFactory 類。

  • plugins --- 用于配置一系列攔截器,用于攔截映射 SQL 語句的執(zhí)行??梢酝ㄟ^實(shí)現(xiàn) Interceptor 接口來實(shí)現(xiàn)自己的攔截器。

  • environments --- 用于配置數(shù)據(jù)源信息,包括連接池、事務(wù)屬性等。

  • mappers --- 程序中所有用到的 SQL 映射文件都在這里列出,這些映射 SQL 都被 MyBatis 管理。

上面提及的大多數(shù)元素都不是必需的,通常 MyBatis 會(huì)為沒有顯式設(shè)置的元素提供缺省值。一個(gè)簡單的全局配置文件示例如下:

清單 1. 簡單的全局配置文件示例
 <?xml version="1.0" encoding="UTF-8" ?> 
 <!--iBatis 和 MyBatis 的全局配置文件使用不同的 DTD 約束,在將應(yīng)用由
 iBatis 升級(jí)至 MyBatis 時(shí)需要注意(兩者的映射文件 DTD 約束也不相同)--> 
 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> 
 <configuration> 
 <!-- 配置數(shù)據(jù)源相關(guān)的信息 --> 
 <environments default="demo"> 
 <environment id="demo"> 
 <transactionManager type="JDBC"/> 
 <dataSource type="POOLED"> 
 <property name="driver" value= … /> 
 <property name="url" value= … /> 
 <property name="username" value="root"/> 
 <property name="password" value="root"/> 
 </dataSource> 
 </environment> 
 </environments> 
 <!-- 列出映射文件 --> 
 <mappers> 
 <mapper resource="footmark/mybatis/demo/UserInfoMapper.xml"/> 
 </mappers> 
 </configuration>

有了這些信息,MyBatis 便能夠和數(shù)據(jù)庫建立連接,并應(yīng)用給定的連接池信息和事務(wù)屬性。MyBatis 封裝了這些操作,最終暴露一個(gè) SqlSessionFactory 實(shí)例供開發(fā)者使用,從名字可以看出來,這是一個(gè)創(chuàng)建 SqlSession 的工廠類,通過 SqlSession 實(shí)例,開發(fā)者能夠直接進(jìn)行業(yè)務(wù)邏輯的操作,而不需要重復(fù)編寫 JDBC 相關(guān)的樣板代碼。根據(jù)全局配置文件生成 SqlSession 的代碼如下:

 Reader reader = Resources.getResourceAsReader("Configuration.xml"); 
 SqlSessionFactory sqlSessionFactory = 
 new SqlSessionFactoryBuilder().build(reader); 
 SqlSession sqlSession = sqlSessionFactory.openSession();

可以把上面的三行代碼看做是 MyBatis 創(chuàng)建 SqlSession 的樣板代碼。其中第一行代碼在類路徑上加載配置文件,Resources 是 MyBatis 提供的一個(gè)工具類,它用于簡化資源文件的加載,它可以訪問各種路徑的文件,不過最常用的還是示例中這種基于類路徑的表示方式。如果讀者對(duì) Hibernate 有所了解,一定會(huì)發(fā)現(xiàn) MyBatis 不論是使用風(fēng)格還是類名都和 Hibernate 非常相像,筆者曾今多次在國內(nèi)外 Java 社區(qū)看到有人說 MyBatis 在向 Hibernate/JPA 靠攏。暫且不論這是否屬實(shí),持久化技術(shù)在經(jīng)過一番蓬勃的競(jìng)爭(zhēng)和發(fā)展,最終在社區(qū)形成統(tǒng)一的認(rèn)識(shí)并被廣泛接受,這對(duì)開發(fā)者而言未必不是一件好事,MyBatis 在這一點(diǎn)上只是向事實(shí)上的標(biāo)準(zhǔn)靠近了一步。

在完成全局配置文件,并通過 MyBatis 獲得 SqlSession 對(duì)象之后,便可以執(zhí)行數(shù)據(jù)訪問操作了。對(duì)于 iBatis/MyBatis 而言,要執(zhí)行的操作其實(shí)就是在映射文件中配置的 SQL 語句。兩者的配置基本相同,如下所示:

清單 2. 在映射文件中配置 SQL 語句
 <?xml version="1.0" encoding="UTF-8" ?> 
 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
 <mapper namespace="mybatis.demo.UserInfoMapper"> 
 <select id="selectUser" parameterType="int"
 resultType="mybatis.demo.UserInfo"> 
 select * from UserInfo where userid =#{userid} 
 </select> 
 </mapper>

在 iBatis 中,namespace 不是必需的,且它的存在沒有實(shí)際的意義。在 MyBatis 中,namespace 終于派上用場(chǎng)了,它使得映射文件與接口綁定變得非常自然。關(guān)于接口綁定,后面會(huì)有篇幅專門描述。使用 SqlSession 執(zhí)行 SQL 的方式如下:

清單 3. 使用 SqlSession 執(zhí)行映射文件中配置的 SQL 語句
 try 
 { 
 UserInfo userinfo = (UserInfo) sqlSession.selectOne 
 ("mybatis.demo.UserInfoMapper.getUser", 2); 
 System.out.println(userinfo); 
 } finally 
 { 
 sqlSession.close(); 
 }

需要注意的是,SqlSession 的使用必需遵守上面的格式,即在 finally 塊中將其關(guān)閉。以保證資源得到釋放,防止出現(xiàn)內(nèi)存泄露!

以上就是一個(gè)簡單而完整的 MyBatis 程序。其中涉及了全局配置文件,映射文件,構(gòu)建 SqlSession 對(duì)象,執(zhí)行數(shù)據(jù)訪問操作等四個(gè)步驟。下面將針對(duì)除構(gòu)建 SqlSession 對(duì)象之外的三塊內(nèi)容進(jìn)行分解。

回頁首

MyBatis 全局配置文件的改變

MyBatis 全局配置文件的各主要元素基本和 iBatis 相同,只是在用法和個(gè)別名稱上做了調(diào)整。元素的意義就不再描述,下面主要講述針對(duì) iBatis 和 MyBatis 配置文件的主要區(qū)別之處。

首先,兩個(gè)版本的 DTD 約束不同,MyBatis 的 DTD 文件已經(jīng)包含在發(fā)布包下的 mybatis-3.0.x.jar 包中。這直接影響到的是,iBatis 配置文件的根元素是 <sqlMapConfig>,而 MyBatis 使用的是 <configuration>。

其次,<settings> 的用法發(fā)生了改變,之前的格式為:

清單 4. 在 iBatis 中設(shè)置屬性的方式
 <settings props1="value1" props2="value2"… />

要設(shè)置的屬性直接以鍵值對(duì)的形式作為 <settings> 的屬性。而在 MyBatis 中調(diào)整為略顯復(fù)雜但卻更有條理的方式:

清單 5. 在 MyBatis 中設(shè)置屬性的方式
 <settings> 
 <setting name="props1" value="value1"/> 
 <setting name="props2" value="value2"/> 
……
 </settings>

另外,之前配置事務(wù)管理器和數(shù)據(jù)源的方式如下:

清單 6. 在 iBatis 中配置事務(wù)管理器和數(shù)據(jù)源的方式
 <transactionManager type="JDBC" > 
 <dataSource type="SIMPLE"> 
 <property name="JDBC.Driver" value="${driver}"/> 
 <!-- 其他數(shù)據(jù)源信息省略 --> 
 </dataSource> 
 </transactionManager>

在 MyBatis 中調(diào)整為如下的方式:

清單 7. 在 MyBatis 中配置事務(wù)管理器和數(shù)據(jù)源的方式
 <environments default="demo"> 
 <environment id="demo"> 
 <transactionManager type="JDBC"/> 
 <dataSource type="POOLED"> 
 <property name="JDBC.Driver" value="${driver}"/> 
 <!-- 其他數(shù)據(jù)源信息省略 --> 
 </dataSource> 
 </environment> 
 </environments>

通過 <environments> 來進(jìn)行數(shù)據(jù)源管理,主要是為了簡化在多套數(shù)據(jù)源配置之間的切換,比如開發(fā)和發(fā)布使用不同的配置。

最后,在 iBatis 中指定映射文件的方式如下:

清單 8. 在 iBatis 中指定映射文件的方式
 <sqlMap resource=... /> 
 <sqlMap resource=... /> 
 <sqlMap resource=... />

在 MyBatis 中調(diào)整為如下方式:

清單 9. 在 MyBatis 中指定映射文件的方式
 <mappers> 
 <mapper resource=... /> 
 <mapper resource=... /> 
 </mappers>

上面的這些調(diào)整,主要出發(fā)點(diǎn)其實(shí)并不是使得 MyBatis 功能更為強(qiáng)大,而是使配置更為合理,讓開發(fā)者更容易閱讀和理解。

到目前為止,我們主要討論了 XML 形式的全局配置,其實(shí)這也不是唯一選擇,MyBatis 還提供了通過代碼來進(jìn)行配置的方式:

清單 10. 在 MyBatis 中使用代碼進(jìn)行配置
 DataSource ds = …… // 獲取一個(gè) DataSource 
 TransactionFactory txFactory = new JdbcTransactionFactory(); 
 Environment env = new Environment("demo", txFactory, ds); 
 Configuration cfg = new Configuration(env); 
 cfg.addMapper(UserInfoMapper.class); 
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfg);

結(jié)合前面的配置文件,很容易理解這段代碼的意思,故不再贅述。不過,需要注意的是 Configuration 的 addMapper() 方法,該方法的參數(shù)通常是一個(gè)接口,可以在接口里面定義若干方法,在方法上使用注解來指定映射的 SQL 語句。一個(gè)典型的接口定義以及對(duì)應(yīng)的數(shù)據(jù)訪問方法如下:

清單 11. 將映射的 SQL 語句與接口中的方法綁定
 // 映射 SQL 綁定接口
 public interface UserInfoMapper 
 { 
 @Select("select * from userinfo where userid = #{userid}") 
 public UserInfo getUserInfo(int userid); 
 } 
 // 接口綁定對(duì)應(yīng)的數(shù)據(jù)訪問方法
 try 
 { 
 //UserInfo userinfo = (UserInfo) sqlSession.selectOne 
 ("mybatis.demo.UserInfoMapper.selectUser", 2); 
 UserInfoMapper userinfoMapper = 
 sqlSession.getMapper(UserInfoMapper.class); 
 UserInfo userinfo = userinfoMapper.getUserInfo(1); 
 System.out.println(userinfo); 
 } finally 
 { 
 sqlSession.close(); 
 }

回頁首

MyBatis 映射文件的改變

MyBatis 針對(duì)映射文件進(jìn)行格式調(diào)整的地方很多,但大部分僅僅只是名稱上的變化,現(xiàn)代的 IDE 都支持聯(lián)想功能,可以很方便的獲取到當(dāng)前位置可以有哪些元素、哪些屬性等。所以這基本不會(huì)給開發(fā)者造成什么麻煩。

針對(duì)映射文件,首先是一系列的屬性名稱的改變,這些僅僅是名稱的改變,用法和含義并沒有發(fā)生變化:

  • 和全局配置文件一樣,由于 DTD 約束發(fā)生變化,根元素也由原來的 <sqlMap> 調(diào)整為 <mapper>。

  • <select> 等元素的 parameterClass 屬性改為了 parameterType 屬性。

  • <select> 等元素的 resultClasss 屬性改為了 resultType 屬性。

  • <parameterMap> 等元素的 class 屬性改為了 type 屬性。

  • <result> 元素的 columnIndex 屬性被移除了。

  • 嵌套參數(shù)由 #value# 改為了 #{value}。

  • <parameter> 等元素的 jdbcType 屬性取值中,原來的 "ORACLECURSOR" 取值改為了現(xiàn)在的 "CURSOR","NUMBER" 取值改為了 "NUMERIC"。

iBatis/MyBatis 對(duì)存儲(chǔ)過程的支持一直是值得稱道的。之前通過使用 <procedure> 元素進(jìn)行存儲(chǔ)過程的定義,示例如下:

清單 12. iBatis 中調(diào)用存儲(chǔ)過程的方式
 <procedure id="getValues" parameterMap="getValuesPM"> 
    { ? = call pkgExample.getValues(p_id => ?) } 
 </procedure>

在 MyBatis 中,<proccedure> 元素已經(jīng)被移除,通過 <select>、<insert> 和 <update> 進(jìn)行定義:

清單 13. MyBatis 中調(diào)用存儲(chǔ)過程的方式
 <select id="getValues" parameterMap="getValuesPM" statementType="CALLABLE"> 
    { ? = call pkgExample.getValues(p_id => ?)} 
 </select>

如上所示,通過 statementType 屬性將該語句標(biāo)識(shí)為存儲(chǔ)過程而非普通 SQL 語句。

源碼來源:×××/technology

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時(shí)售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價(jià)比高”等特點(diǎn)與優(yōu)勢(shì),專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場(chǎng)景需求。

分享名稱:鳳凰涅槃:從iBatis到MyBatis-創(chuàng)新互聯(lián)
本文鏈接:http://bm7419.com/article26/dpojcg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)網(wǎng)站內(nèi)鏈、網(wǎng)站制作、企業(yè)網(wǎng)站制作定制開發(fā)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站優(yōu)化排名