iBatis2 SqlMap中常用sql語句

來源:互聯網
上載者:User

標籤:ibatis   sql   動態sql   sqlmap   

本來我也不喜歡iBatis,那是因為我當時還不怎麼會用它,現在我想說,iBatis是個好東西,不信你試試看。下面是我在項目實踐中對iBatis的一個小總結,希望協助眾多在疲於iBatis編碼而無暇思考的苦工們找到一些偷懶的機會。 SqlMap的配置是iBatis中應用的核心。這部分任務佔據了iBatis開發的70的工作量。
1、命名空間:  <sqlMap namespace="Account">,在此空間外要引用此空間的元素,則需要加上命名空間名。 2、實體的別名:  <typeAlias alias="Account" type="com.lavasoft.ibatissut.simple.domain.entity.Account"/>  如果有用到的全名的地方,可以用別名代替,受命名空間約束。 3、插入操作    對於自增主鍵的表,插入可以不配置插入的主鍵列。否則是必須的。 4、擷取主鍵     插入語句之前配置:主要是針對Sequence主鍵而言,插入前必須指定一個主鍵值給要插入的記錄。Oracle、DB2亦如此,方法是在插入語句標籤<insert....>之前配置上:    <insert id="insertAccount" parameterClass="Account">
        <selectKey resultClass="long" keyProperty="sctId">
            SELECT SEQ_TEST.NEXTVAL FROM DUAL
        </selectKey>   
        insert into .... ........    </insert>      插入語句之後配置:蛀牙是針對自增主鍵的表而言,這類表在插入時不需要主鍵,而是在插入過程自動擷取一個自增的主鍵。比如MySQL    <insert id="insertAccount" parameterClass="Account">
        <selectKey resultClass="long" keyProperty="sctId">
            SELECT LAST_INSERT_ID() 
       </selectKey>           insert into .... ........    </insert>    當然,是否需要配置<selectKey>根據情況,只要能保證記錄有主鍵即可。一旦配置了<selectKey>,就可以在執行插入操作時擷取到新增記錄的主鍵。  6、SQL入參parameterClass  插入語句入參:parameterClass="類別名"  來設定。  查詢語句入參:可以設定類別名,也可以設定為map,也可以設定為iBatis支援的原生類型(比如string、int、long等),當只有一個原生類型入參時,則在SQL中用value關鍵字來引用。比如:    <select id="getById"  parameterClass="long" resultMap="result_base">
        select * from customer where id = #value#
    </select>    map是最強大的入參方式,任何入參方式都可以轉換為這種入參方式,因為iBatis僅接受一個入參,當幾個參數分布在不同對象中的時候,將這些對象的屬性(或者對象本身put)到map中,然後一次傳遞給sql語句是非常有效。可以自己寫一個將對象或者對象集合轉換為map的工具(我已經實現一個了)。    另外,map的中的元素(比如pobj)是個複雜物件,則還可以在SQL中以#pobj.protyename#的格式來引用其中內嵌的屬性。當然不推薦這麼幹。 7、返回值參數類型      返回值參數也同樣有兩種類型,一種是物件類型resultClass="Account",一種是resultMap="AccountResult"。這兩種類型的選擇常常會令人迷惑不解,一言明其理:當結果集列名和類屬性名稱完全對應的時候,則應該使用resultClass來指定查詢結果類型。當然有些列明不對應,可以在sql中使用as重新命名達到一致的效果。 當查詢結果列名和類屬性名稱對應不上的時候,應該選擇resultMap指定查詢結果集類型。否則,則查詢出來填充的對象屬性為空白(數位為0,對象的為null)。 但是實際上resultMap是對一個Java Bean的映射,需要先定義xml的映射後,才可以引用,例如:    <resultMap id="AccountResult" class="Account">
        <result property="id" column="ACC_ID"/>
        <result property="firstName" column="ACC_FIRST_NAME"/>
        <result property="lastName" column="ACC_LAST_NAME"/>
        <result property="emailAddress" column="ACC_EMAIL"/>
    </resultMap>    resultMap映射的結果的目的就是要將查詢的結果集綁定到映射對象的屬性上。    不管使用哪種返回值參數類型,其最終目的就是要把每條記錄映射到一個類的對象或者對象集合上,如果有某個類屬性對應不上,則在得到的這個對象或對象集合中這個屬性為空白。映射的屬性可以是表與實體中的一部分。不要同時使用兩種返回值參數類型,這樣只會令人迷惑。 8、查詢結果集分組    查詢結果集排序有兩種方式:一是在結果集映射上定義<resultMap id="result" class="bar" groupBy="id">,另一種就是在SQL語句中分組。建議在SQL語句中分組,以獲得更大的可控制性。 9、SQL中參數的引用     SQL中引用parameterClass的參數有三種方式:     iBatis內建支援的類型,比如int、string,使用#value#來引用,這個value是關鍵字,不可變。     map類型的參數,使用#keyName#來引用,keyName為鍵名。     複雜物件的參數,使用#propertyName#來引用,propertyName類屬性的名字。 10、模糊查詢中參數的引用    模糊查詢是針對字串而言的,如果遇到兩個單引號要包含一個參數,則不能再用#來引用變數了,而應該改為$,比如:‘%$varName$%‘,當然,也可以使用 ‘%‘ || #varname# || ‘%‘ 來繞過此問題。 11、SQL片段       可以通過<sql id="sql_xxx">...</sql>定義SQL片段,然後<include refid="sql_xxx"/>來在各種語句中引用。達到服用目的, 12、動態SQL      可以通過使用動態SQL來組織靈活性更大的更通過的SQL,這樣極大減少了編碼量,是iBatis應用的第二大亮點。     比如:一個動態where條件                <dynamic prepend="where">
                        <isNotEmpty prepend="and" property="$$$$$">
                                $name like ‘%‘|| #$name# ||‘%‘
                        </isNotEmpty>
                        <isGreaterThan prepend="and" property="$$$$$" compareValue="$$$number">
                                $code like ‘%‘|| #$code# ||‘%‘
                        </isGreaterThan>
                </dynamic>     當然,prepend表示連結關鍵字,可以為任何字串,當為sql關鍵字時,iBatis自動判斷是否應該添加該關鍵字。該文法也很簡單,關鍵是要會用心思考組織動態SQL。    這裡面有一點要注意:區別<isNotEmpty>和<isNotNull>區別,當為空白空串時<isNotEmpty>返回true,當為空白串時<isNotNull>返回真。哈哈,自己體會吧,說了反而囉嗦。 13、結果集映射繼承結果集映射的繼承的目的是為了映射定義的複用,比如下面定義了兩個映射,AccountResult繼承了base:
    <resultMap id="base" class="Account">
        <result property="id" column="ACC_ID"/>
        <result property="firstName" column="ACC_FIRST_NAME"/>
        <result property="lastName" column="ACC_LAST_NAME"/>
    </resultMap>
    <resultMap id="AccountResult" class="Account" extends="Account.base">
        <result property="emailAddress" column="ACC_EMAIL"/>
    </resultMap>
這樣,就很容易擴充了一個映射策略。
       14、查詢注入查詢注入是在一個查詢中嵌入另外一個查詢,這樣做的目的是為了實現實體物件之間的關聯關聯關係(一對一、一對多、多對多)分單項雙向。有關這些內容,是比較複雜的,筆者對此做了深入研究,並分別寫了三篇來講述。 查詢注入的實現就是在實體屬性為另外一個實體或者實體集合的時候,引入一個相關的查詢來實現,例如,客戶和訂單的映射關係:public class Customer {
    private Long id;
    private String name;
    private String address;
    private String postcode;
    private String sex;
    private List<Orders> orderlist = new ArrayList<Orders>();     <resultMap id="result" class="customer">
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="address" column="address"/>
        <result property="postcode" column="postcode"/>
        <result property="sex" column="sex"/>
        <result property="orderlist" column="id" select="orders.findByCustomerId"/>
    </resultMap> 在這個映射中,為了查詢客戶的時候,能查詢到相關的訂單,可以在映射orderlist屬性的時候,將其指向另外一個查詢orders.findByCustomerId,這個查詢是以Customer的id為參數來查詢的。 select="orders.findByCustomerId"這個查詢定義如下:    <select id="findByCustomerId" resultMap="result_base" parameterClass="long">
        select * from orders where customerId = #value#
    </select> 原理就是這麼簡單,然後根據實際情況,可以自由實現實體間的關聯關係。 14、iBatis的分頁查詢iBatis的分頁有兩種方式,一點都不神秘,不要被網上的流言所迷惑。第一種方式:結果集篩選分頁。先執行部分頁的SQL查詢語句,然後得到一個ResultSet,然後根據分頁範圍選取有效記錄填充到對象中,最終以集合的形式返回。對於10w條一下的記錄的表,不存在效能問題,如果存在,你可以選擇第二中方式。第二種方式:SQL分頁,通過組裝分頁類型的SQL來實現分頁。這個關鍵在於分頁參數的傳遞和分頁SQL的構建。分頁SQL構件每種資料庫都不一樣,不說了。分頁參數的傳遞卻可以通用。我主張用map分裝入參,連同分頁參數一塊傳遞進來,就搞定了。如果原來沒有考慮到分頁,而用的是對象做參數,則可以通過apache 的 beanutils組件來實現一個object到map之間的轉換工具,問題迎刃而解。 當然,這還不是分頁查詢應用的最高境界。思考,分頁需要計算一個總記錄數,記錄數執行的sql返回值是count(?),條件是除了分頁以外的條件,因此應該將查詢SQL靜態分開,以MySQL為例,可以將查詢分為查什麼,和什麼條件兩部分,在條件部分對分頁參數進行動態判斷,如果分頁參數就不分頁,如果有則分頁。這樣最後只需要兩個組裝的sql就可以計算總數和分頁查詢了。大大簡化了問題的難度。 Oracle的解決思路也一樣,不一樣的地方就是拼裝分頁SQL改變了。 15、執行預存程序的配置SQL Map 通過<procedure>元素支援預存程序。下面的例子說明如何使用具有輸出參數
的預存程序。 
    <parameterMap id="swapParameters" class="map">
        <parameter property="email1" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
        <parameter property="email2" jdbcType="VARCHAR" javaType="java.lang.String" mode="INOUT"/>
    </parameterMap>
    <procedure id="swapEmailAddresses" parameterMap="swapParameters">
        {call swap_email_address (?, ?)}
    </procedure> 
調用上面的預存程序將同時互換兩個欄位(資料庫表)和參數對象(Map)中的兩個 email地址。如果參數的 mode 屬性設為 INOUT 或 OUT,則參數對象的值被修改。否則保持不變。 
注意!要確保始終只使用 JDBC 標準的預存程序文法。參考 JDBC 的 CallableStatement
文檔以獲得更詳細的資訊。 16、就是iBatis中各種id的命名了,這個看起來小菜一碟,但是搞砸了會很痛苦。建議如果有DAO層的話,DAO介面的名字和SQL語句id的名字保持一致。同時,在DAO中將save和update封裝為一個方法(從Hibernate中學來的),這是非常好的。也可以直接在SQL層將插入和更新柔和在一塊,太複雜,有點影響效率,這見機行事了。    另外Spring提供了各種資料操作模板,通過模板,擦做資料也就是“一句話”的問題,寫個DAO還有必要麼,尤其對iBatis來說,根本沒有必要。這樣,就需要在領域活動層的設計上下功夫了。 17 、iBatis的查詢也可以配置緩衝策略,緩衝的配置很複雜,分很多中情況,可以參看附件中的iBATIS-SqlMaps-2_cn.pdf的39頁內容,有詳細介紹。 18、偷懶的最高境界,讓程式去幹哪裡80%的體力活。自己僅僅把把關。任何重複的活動都有規律可循的,一旦發現了其中的規律,你就可以想辦法把自己從中解脫出來。    iBatis也不例外,每個表都有增刪改查、分頁等操作。對應在每個DAO方法上亦如此。可以通過資料庫產生sqlmap、entity、dao,然後將這些東西改吧改吧就完成大部分的工作量。本人已經實現過了,當然開發這個工具的前提是你對iBatis有深入研究和理解。 -------------------------------------------------下面是iBatis開發指南中內容: 附錄:容易出錯的地方 
本附錄是譯者添加的,列出了初學者容易出錯的地方,作為完成快速入門課程後的學習
筆記,可以讓初學者少走些彎路。僅供參考。 
1)  在 parameterMap 和 resultMap 中,欄位資料類型是 java.sql.Types 類定義的常量名
稱。常用的資料類型包括 BLOB,CHAR,CLOB,DATE,LONGVARBINARY, 
INTEGER,NULL,NUMERIC,TIME,TIMESTAMP 和 VARCHAR 等。 
2)  對於資料表中 NULLABLE 的欄位,必須在 parameterMap 和 resultMap 中指定欄位
的資料類型。 
3)  對於資料類型是 DATE,CLOB 或 BLOB 的欄位,最好在 parameterMap 和 resultMap中指定資料類型。 
4)  對於二進位類型的資料,可以將 LONGVARBINARY 映射成 byte[]。 
5)  對於文本類型較大的資料,可以將 CLOB 映射成 String。 
6) Java Bean 必須擁有預設的構造器(即無參數的構造器)。 
7) Java Bean 最好實現 Serializable 介面,以備應用的進一步擴充。 本人認為:盡量避免在每個入參後面附加參數的類型。以保持配置簡潔,並且本人在長期開發中,沒有發現必須要那麼做。原文出自:http://lavasoft.blog.51cto.com/62575/83902/

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

iBatis2 SqlMap中常用sql語句

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.