亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Spring與iBATIS的集成

2019-11-18 12:58:37
字體:
來源:轉載
供稿:網友

iBATIS似乎已遠離眾說紛紜的OR框架之列,通常人們對非常流行的Hibernate情有獨鐘。但正如SPRing: A Developer's Notebook作者BrUCe Tate 和Justin Gehtland所說的那樣,與其他的OR框架相比,iBATIS獨辟蹊徑:“iBATIS不是試圖從根本上掩蓋SQL,實際上,它是在擁抱SQL?!?br />
但別犯愁:SQL本身具備了一些重要的功能,并且通過模板的使用,在Spring應用中采用iBATIS顯得輕而易舉。在此摘錄中,兩位作者將和你一起安裝iBATIS并將其集成進你的Spring應用中。他們也闡明了怎樣取得你已編寫的SQL語句及把他們映射給iBATIS使用的Bean。最后,還討論了iBATIS的優缺點,及為什么是這樣的一種方式,即所謂的“在完全OR與JDBC之間的一個幽雅的折衷?!?br />
就象Developer's Notebook 系列中所有的書一樣,你將由直接的且實用的方式獲得信息,這些信息包含了完成你工作所需的細節。換言之:“一切來自實戰,沒有講義?!?br />
版權聲明:任何獲得Matrix授權的網站,轉載時請務必保留以下作者信息和鏈接
作者:czyczy(作者的blog:http://blog.matrix.org.cn/page/czyczy)
原文:http://www.matrix.org.cn/resource/article/44/44304_Spring+iBATIS.Html
要害字:Spring;iBATIS

對象關系持久化(OR Persistence)

本章所涉及的內容為:
· 與iBATIS的集成
· 在Spring的應用中使用JDO
· 在Spring的應用中使用Hibernate
· 運行測試用例

離我住處不遠的地方,名為啤酒山的山上有一個臭名遠揚的山地自行車道。我想不出它為何會得到這樣的名字,因為在下山的時候你要保持完全地清醒甚至于聚精會神。據我所知,那決不是純粹的攀爬(或不曾離開自行車步行)。大多數人認為那很荒謬,哪怕只是去嘗試一下而已。這座山連綿起伏,異常陡峭,它的表面覆蓋了松散的巖石和大量的巖脊。我想我一定是太厭煩我的余生了,因為兩年半來我一直不斷地在攀爬。在我看來,那樣的一座山峰就像是一個困難的編程問題。我已多次重新啟程,在到達山峰的途中,嘗試過翻越許多巖脊和泥礫叢的不同途徑。為了攀爬啤酒山, 我需要改良自行車,提高車技,加強練習。

java 開發人員而言,對象關系映射已然成為那類問題了。我們需要處理功能(processing power)、較佳設計模式及更好持久化框架的組合,從而使解決持久化設計變得更加清楚。最終,我們開始取得實質性的進展?,F在,我們已逼近山峰,象Spring這樣的框架就象是方程式的一部分,因為他們讓對象關系映射(ORM)花較少的精力來做更多的事情。在本章中,你將看到三種框架:iBATIS, JDO及Hibernate:

·iBATIS 是一種JDBC助手類框架,它給了你一些OR映射及使用OR的好處,但不帶 有太多的風險。
·JDO是一種飽受爭議的持久化標準,但它有著一些獨特的實現,這使得JDO在行業中也算得上是最完美的持久化框架之一。
·Hibernate 是在JBoss組織控制下的一開源持久化框架。它可能是時下最為流行的持久化框架。大量的客戶采用它,而且客戶的數量還在持續穩定地增長。        

在本章中,我們會對所提的三個框架進行嘗試,而不必對應用的其余部分的代碼做任何變更。

與iBATIS集成

常言道:“樹大招風”。在大肆宣揚的J2EE和.Net之爭中, Sun的一示例應用程序被用來作為衡量應用服務器在運行時的各項性能的核心基準。 .Net非常好地打敗了基于EJB的J2EE版本, 且方興未艾。Clinton Begin 開發了iBATIS的持久化框架,他在iBATIS中使用PetStore的簡化版,且自從那以后iBATIS就越來越流行。Spring提供非常優良的與iBATIS的集成功能, 在此章中將對其進行介紹。

并非所有的問題都非常適合持久化框架這朵盛開的花朵,中等難度的問題是最合適的環境。沒有正確的技巧或不相當的問題,可能就會誤入歧途。跟我一起教課的Ted Neward, 他是《Effective Enterprise Java》一書的作者,他經常把構建或采用持久化框架與美國的越南戰爭拿來做比較,進入這樣的兩場戰爭是很誘人的,但最終都很難贏得勝利,而且此二例中并不存在著行之有效的策略。關于這一話題,你仍可查閱http://www.neward.net上的相關內容。

然而,我不想扯得太遠。嘗試一下象iBATIS SqlMaps的框架給了你OR的使用模型又何嘗不可呢?當然,我們不會強迫你一口吞下一只大象。具體來說,iBATIS讓你:
·映射字段和SQL語句到要害字
·使用SQL的全部功能而沒有乏味的JDBC
·從你的代碼中剝離SQL
Spring 與iBATIS的集成給了你這些及更多的裨益, 讓我們為此而忙乎起來。

我該怎么做?


首先,你需要安裝iBATIS。由于iBATIS的配置會在你的Spring 應用上下文中完成,因此你不需要立即配置它。在http://www.ibatis.com/(譯注:最新的網址為:http://ibatis.apache.org/,iBATIS已于2004-08-16并入Apache 軟件基金會)上可以下載并安裝。在本書中我們使用1.3.1版本。把iBATIS提供的jars(ibatis-sqlmap.jar, ibatis-dao.jar, and ibatis-common.jar)和Spring提供的jdom.jar(在Spring的/lib 目錄下)放到你的項目目錄/war/WEB-INF/lib中。

You’ve already got the interface for the façade and the model, so you need an implementation of the façade and the SQL statement.  First, you can implement the façade for the application, as in Example 5-1.
你已經有了門戶(façade)和模型(model)的接口,因而你需要facade和SQL語句的實現。首先,你可以象示例5-1那樣,在你的應用中實現façade的接口。

示例 5-1 IBatisRentABike.java

public class IBatisRentABike extends SqlMapDaoSupport
                 implements RentABike {

        private String storeName ="";

        public void setStoreName(String storeName) {
                this.storeName= storeName;
        }

        public String getStoreName( ) {
                return this.storeName;
        }

        public List getBikes() {
                return getSqlMapTemplate().executeQueryForList("getBikes", null);
        }

        public Bike getBike(String serialNo) {
                return (Bike) getSqlMapTemplate().
                        executeQueryForObject("getBikeBySerialNo", serialNo);
        }

        public Bike getBike(int bikeId) {
                return (Bike) getSqlMapTemplate().
                        executeQueryForObject("getBikeByID", new Integer(bikeId));
        }

        public void saveBike(Bike bike) {
                getSqlMapTemplate().executeUpdate("saveBike", bike);
        }

        public void deleteBike(Bike bike) {
                getSqlMapTemplate().executeUpdate("deleteBike", bike);
        }

        public List getCustomers() {
                return getSqlMapTemplate().executeQueryForList("getCustomers", null);
        }

        public Customer getCustomer(int custId) {
                return (Customer) getSqlMapTemplate().
                    executeQueryForObject("getCustomer", new Integer(custId));
        }
        
        public List getReservations() {
                return getSqlMaptemplate().
                    executeQueryForList("getReservations", null);
        }

        public List getReservations(Customer customer) {
                return getSqlMaptemplate().
                    executeQueryForList("getReservationsForCustomer", customer);
        }

        public List getReservations(Bike bike) {
                return getSqlMaptemplate().
                    executeQueryForList("getReservationsForBike",bike);
        }

        public List getReservations(Date date) {
                return getSqlMaptemplate().
                    executeQueryForList("getReservationsForDate", date);
        }

        public Reservation getReservation(int resId) {
                return getSqlMaptemplate().
                    executeQueryForObject("getReservation", new Integer(resId));
        }
}


這些就是命名式查詢。iBATIS將每一查詢分成一個獨立的映射,那樣你就可以用名字來執行查詢。

SqlMapTemplate由Spring的SqlMapDaoSupport 類提供,我們的RentABike實現必須來繼續這個類。SqlMapTemplate負責建立和治理底層數據存儲的連接,同時也解釋了你所提供的映射文件。你可以把template 看成是你對于iBATIS命名式查詢所做那些事情的默認實現。

你也需要創建SQL語句,可以給每條SQL語句取一個名字。然后,把結果映射給Java Bean。在這里你有兩種選擇,你可以在SQL中把每個Bean屬性作為別名來引用,或在查詢和Bean 之間建立顯式映射,就象示例5-2那樣。在此例中我們也建立了Customer 與Reservation的映射。

示例5-2.  Bike.xml(iBATIS SQL 映射文件)
<?xml version="1.0" encoding="UTF-8" ?>


<sql-map name="Bike" >
    <result-map name="result" class="com.springbook.Bike" >
       <property name="bikeId" column="bikeId" columnIndex="1" />
       <property name="manufacturer" column="manufacturer" columnIndex="2" />
       <property name="model" column="model" columnIndex="3" />
       <property name="frame" column="frame" columnIndex="4" />
       <property name="serialNo" column="serialNo" columnIndex="5" />
       <property name="weight" column="weight" columnIndex="6" />
       <property name="status" column="status" columnIndex="7" />
    </result-map>
    
    <mapped-statement name="getBikes" result-map="result">
        select bikeId, manufacturer, model, frame, serialNo, status
        from bikes
    </mapped-statement>

    <mapped-statement name="getBikeBySerialNo" result-map="result">
        select bikeId, manufacturer, model, frame, serialNo, status
        from bikes
       where serialNo=#value#
    </mapped-statement>

    <mapped-statement name="getBikeByID" result-map="result">
        select bikeId, manufacturer, model, frame, serialNo, weight, status
        from bikes
        where bikeId=#value#
    </mapped-statement>

    <mapped-statement name="saveBike" >
        insert into bikes
        (bikeId, manufacturer, model, frame, serialNo, weight, status)
        values(#bikeId#, #manufacturer#, #model#, #frame#, #serialNo#,
        #weight#, #status#)
    </mapped-statement>

    <mapped-statement name="deleteBike" >
        delete from bikes
        where bikeId = #bikeId#
    </mapped-statement>
</sql-map>


示例5-3. Customer.xml
<?xml version="1.0" encoding="UTF-8" ?>


<sql-map name="Customer" >
    <result-map name="result" class="com.springbook.Customer" >
       <property name="custId" column="custId" columnIndex="1" />
       <property name="firstName" column="firstName" columnIndex="2" />
       <property name="lastName" column="lastName" columnIndex="3" />
    </result-map>
    
    <mapped-statement name="getCustomers" result-map="result">
            select custId,
                    firstName,
                    lastName
             from customers
    </mapped-statement>

    <mapped-statement name="getCustomer" result-map="result">
            select custId,
                    firstName,
                    lastName
            from customers
            where custId = #value#
    </mapped-statement>
</sql-map>


示例 5-4. Reservation.xml
<?xml version="1.0" encoding="UTF-8" ?>


<sql-map name="Reservation" >
    <result-map name="result" class="com.springbook.Customer" >
       <property name="reservationId" column="resId" columnIndex="1" />
       <property name="bike" column="bikeId" columnIndex="2" />
       <property name="customer" column="custId" columnIndex="3" />
       <property name="reservationDate" column="resDate" columnIndex="4" />
    </result-map>
    
    <mapped-statement name="getReservations" result-map="result">
            select resId,
                   bikeId,
                              custId,
                              resDate          
             from reservations
    </mapped-statement>

    <mapped-statement name="getReservationsForCustomer" result-map="result">
            select resId,
                   bikeId,
                              custId,
                              resDate          
             from reservations
             where custId = #value#
    </mapped-statement>

    <mapped-statement name="getReservationsForBike" result-map="result">
            select resId,
                   bikeId,
                              custId,
                              resDate          
             from reservations
             where bikeId = #value#
    </mapped-statement>

    <mapped-statement name="getReservationsForDate" result-map="result">
            select resId,
                   bikeId,
                              custId,
                              resDate          
             from reservations
             where resDate = #value#
    </mapped-statement>

    <mapped-statement name="getReservation" result-map="result">
            select resId,
                   bikeId,
                              custId,
                              resDate          
             from reservations
             where resId = #value#
    </mapped-statement>
</sql-map>


The <result-map> portion provides an eXPlicit map between columns in the database and properties of a persistent class.  The <mapped-statement> can then simply define the SQL queries necessary to execute the needed functionality, and the map handles creation of the resultant Java object.  In addition to the Bike version above, your application currently also requires a map for Customer and Reservation.
<result-map>部分提供了數據庫字段與持久化類屬性之間的一顯式映射。<mapped-statement>接著可以簡單定義運行所需功能的必要的SQL查詢,而映射負責創建合成的Java 對象。除了上述的Bike 版本之外,你的應用程序目前也需要一個關于Customer 和Reservation的映射。

你將不得不做一些OR框架通常為我們所做的活,如創建標識符。在此例中,你將使用MySQL生成的序列(就是數據庫表中的那些AUTO_INCREMENT字段)。你只需在數據庫表定義時簡單地把bikeId標為AUTO_INCREMENT,這樣當增加一條新記錄時,你就可以在SQL語句中略過bikeId字段。我們映射中SaveBike語句就成了示例5-5。

示例5-5. Bike.xml
    <mapped-statement name="saveBike" >
        insert into bikes
        (manufacturer, model, frame, serialNo, weight, status)
        values(#manufacturer#, #model#, #frame#, #serialNo#, #weight#,
        #status#)
    </mapped-statement>


若你是在使用Oracle, Spring和iBATIS也支持Oracle生成的序列。

下一步,你可以更新應用上下文,且需要列出我們的新fa&ccedil;ade,而fa&ccedil;ade要有SQL映射。把SQL 引入PROPERTIES 文件,就象我們對待JDBC 的參數一樣。 此外,你還需要配置事務策略。( 示例5-6)

示例5-6. .RentABikeApp-servlet.xml
<beans>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>com.mysql.jdbc.Driver</value>
</property>
<property name="url">
<value>jdbc:mysql://localhost/bikestore</value>
</property>
<property name="username">
<value>bikestore</value>
</property>
</bean>
<bean id="rentaBike" class="com.springbook.IBatisRentABike">
<property name="storeName"><value>Bruce's Bikes</value></property>
<property name="dataSource"><ref local="dataSource"/></property>
<property name="sqlMap"><ref local="sqlMap"/></property>
</bean>
<bean id="sqlMap"
class="org.springframework.orm.ibatis.SqlMapFactoryBean">
<property name="configLocation">
<value>/WEB-INF/ibatis.config</value>
</property>
</bean>
<bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource"><ref local="dataSource"/></property>
</bean>


這個事務策略就在應用上下文中,你不必來治理提交適宜,因為Spring 會為你完成。你將在第六章中更完整地探討事務策略。                                                

示例5-7. . ibatis.config
<?xml version="1.0" encoding="UTF-8"?>

<sql-map-config>
<sql-map resource="Bike.xml" />
<sql-map resource="Customer.xml" />
<sql-map resource="Reservation.xml" />
</sql-map-config>


稍后我們會談到事務策略。

發生了什么事?

你沒看到OR映射。OR框架會有意地將一個數據庫表與一個類或多個類關連起來。在此例中,iBATIS會將查詢結果賦予一個類。這意味著iBATIS并未試圖對你隱藏SQL細節。實際上,它是在擁抱SQL。

Spring打算通過模板來簡化iBATIS的使用。iBATIS模板會給出類似JDBC模板的使用模型,你只需指定數據源和iBATIS映射的SQL語句。

當執行SQL語句時,Spring與iBATIS一起為你治理資源,并按要求來創建和關閉連接。Spring會把映射的SQL語句傳給iBATIS, 由iBATIS來運行映射的語句,且若需要,iBATIS會把結果集傳給給你映射SQL語句時所指定的Bean。假如你已有了任何參數,那就可將那些結果集放入hash map中并把結果集傳給帶有映射的SQL語句的模板。

然而,從內部所表現的來看,iBATIS或許并不象是一個OR框架,但使用模型的確有OR的趨向。 構建帶有操作數據存儲的數據訪問對象(data access object),你不會在代碼中看到SQL語句,因為它已被保存在配置文件中了,且iBATIS使用對象集合而不是結果集。簡而言之,這是在全部OR與JDBC之間的一個幽雅的折衷。

關于…

一切都適合iBATIS嗎? 由于這種使用模型與OR模型是那么的相似,且許多應用對他們可能生成的SQL需要有更多的控制,或許你傾向于普遍地使用iBATIS。盡管如此,象JDO和Hibernate的OR框架仍擁有著屬于自己的舞臺。OR框架給了你更多的靈活性和更強大的功能:
·一些高級的對象模型導致了非常復雜的SQL,把這些復雜的SQL交由ORM來完成是最好的處理方式。 例如,繼續通常使得原始的JDBC API操作變得更為復雜。
·一些高級的性能特征,象延遲加載和數據抓取群組,要求對有效地的自動控制需要一個更正式的模型。然而,完美地優化后的JDBC至少要和ORM一樣快速。相對于使用原始的JDBC而言,由ORM提供的性能優化選項對某些類型的問題更獲得較佳性能。
·ORM使某些問題變得更加有趣。操作對象比創建一套的SQL查詢更加簡易。ORM很適合帶有簡單的查找,創建,更新,根據主鍵讀取數據庫中的數據以及刪除記錄的應用。

如若你的應用有快速的數據模型和對象模型的變更,iBATIS就會很適合。假如你有了CRUD類型的應用,那么,使用iBATIS可能就會有點乏味。相反地,假如你正尋找一種好的SQL訪問方式及在ORM和原始的JDBC間有效的折衷,那么,iBATIS可能就會給了你所需的一切。

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
亚洲国产中文字幕在线观看| 久久久久亚洲精品成人网小说| 精品国产一区二区三区久久| 欧美一区二区三区精品电影| 欧美视频不卡中文| 久久精品99无色码中文字幕| 亚洲精品国产精品乱码不99按摩| 国产日本欧美一区二区三区在线| 热久久99这里有精品| 91精品国产91久久久久久吃药| 亚洲精品日韩久久久| 国产在线观看精品一区二区三区| 欧美性极品xxxx做受| 97色在线播放视频| 日韩女在线观看| 欧美色欧美亚洲高清在线视频| 久久精品国产一区二区三区| 国产亚洲成精品久久| 亚洲激情电影中文字幕| 91欧美精品成人综合在线观看| 亚洲伊人久久综合| 国产在线视频欧美| 国产精品欧美激情| 欧美另类极品videosbest最新版本| 中文字幕日韩av| 亚洲精品久久久久久下一站| 久久精品这里热有精品| www高清在线视频日韩欧美| 国产91在线播放九色快色| 久久久国产视频91| 日本国产精品视频| 国产精品99免视看9| 粗暴蹂躏中文一区二区三区| 欧美性猛交99久久久久99按摩| 国产精品一区=区| 日韩风俗一区 二区| 欧美色视频日本版| 亚洲iv一区二区三区| 久久久久久久91| 亚洲成人网在线| 国产日韩中文字幕| 欧美日韩一区二区在线| 国产午夜精品理论片a级探花| 亚洲人精选亚洲人成在线| 性色av一区二区三区| 麻豆一区二区在线观看| 亚洲自拍偷拍网址| 久久6免费高清热精品| 久久久国产精品亚洲一区| 久久久久中文字幕2018| 91美女福利视频高清| 国产婷婷97碰碰久久人人蜜臀| 成人情趣片在线观看免费| 亚洲国产欧美日韩精品| 亚洲乱码一区av黑人高潮| 亚洲国产91精品在线观看| 欧美亚洲在线观看| www.xxxx精品| 亚洲成人av资源网| 欧美日韩国产一中文字不卡| 亚洲精品久久7777777| 日韩av电影在线免费播放| 欧美中文字幕精品| 成人亚洲综合色就1024| 夜色77av精品影院| 疯狂蹂躏欧美一区二区精品| 午夜精品久久久久久久男人的天堂| 午夜精品蜜臀一区二区三区免费| 久久久久久久久电影| 日韩影视在线观看| 九色精品美女在线| 最近2019免费中文字幕视频三| 狠狠躁夜夜躁久久躁别揉| 午夜精品免费视频| 中文精品99久久国产香蕉| 亚洲色图综合网| 日韩精品在线观看网站| 欧美亚洲视频在线看网址| 91精品国产91久久久久| 成人xxxxx| 庆余年2免费日韩剧观看大牛| 欧美成aaa人片在线观看蜜臀| 正在播放欧美一区| 欧美在线视频一区二区| 亚洲第一视频在线观看| 福利视频一区二区| 午夜精品一区二区三区视频免费看| 成人激情av在线| 成人黄色免费看| 精品久久久国产| xxxxxxxxx欧美| 国产精品都在这里| www.精品av.com| 成人亲热视频网站| 亚洲色图15p| 国产精品a久久久久久| 国产精品旅馆在线| 亚洲国产精品人人爽夜夜爽| 中文字幕亚洲一区二区三区| 久久久中精品2020中文| 在线观看国产精品91| 国产精品影片在线观看| 国产一区二区黑人欧美xxxx| 91国产视频在线播放| 精品国产户外野外| 欧美激情视频一区二区三区不卡| 亚洲欧美日韩一区二区在线| 九九热视频这里只有精品| 午夜精品久久17c| 中文字幕一区二区精品| 在线视频中文亚洲| 亚洲精品网站在线播放gif| 日韩视频免费大全中文字幕| 国产999精品视频| 国产91免费看片| 国产又爽又黄的激情精品视频| 欧美在线视频免费观看| 亚洲国产日韩欧美在线99| 久久91精品国产91久久久| 欧美日韩国产一区中文午夜| 国产精品免费视频xxxx| 欧美性猛交xxxx富婆弯腰| 久久久久久久久久久免费| 日本欧美精品在线| 国内成人精品视频| 91精品视频观看| 日韩av男人的天堂| 青草青草久热精品视频在线网站| 亚洲一区精品电影| 日韩小视频在线观看| 久久精品99久久久久久久久| 久久91精品国产91久久久| 91在线直播亚洲| 欧美成人三级视频网站| 欧美视频专区一二在线观看| 国内精品视频一区| 日韩av在线看| 亚洲欧美999| 欧美性色视频在线| 91国内免费在线视频| 国产精品视频一区二区三区四| 欧美夫妻性生活xx| 91大神在线播放精品| 国产日韩在线免费| 91地址最新发布| 国模极品一区二区三区| 欧美激情综合色综合啪啪五月| 精品无人区太爽高潮在线播放| 91天堂在线视频| 97在线免费观看| 欧美性xxxxxx| 欧美激情欧美狂野欧美精品| 国产伦精品一区二区三区精品视频| 国产91精品黑色丝袜高跟鞋| 国产欧美日韩精品丝袜高跟鞋| 亚洲国产成人精品一区二区| 亚洲精品www| 亚洲成人免费在线视频| 久久久久免费视频| 欧美激情在线视频二区| 在线观看日韩专区| 亚洲欧美资源在线| 中文字幕国产精品| 亚洲国产精品成人av|