iBatis映射文件詳解(一)

以下是iBatis映射文件的一個簡單例子:

<?xml version="1.0"encoding="UTF-8" ?>

<!DOCTYPE sqlMap     

   PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"     

   "http://ibatis.apache.org/dtd/sql-map-2.dtd">

<sqlMap>

<cacheModelid=”productCache” type=”LRU”>

<flushInterval hours="24"/>

<flushOnExecute statement="insertStudent"/>

        <flushOnExecute statement="deleteStudentById"/>

<flushOnExecute statement="updateStudentById"/>

<property name=”size” value=”1000” />

</cacheModel>

         <typeAlias alias="Student" type="com.edifier.data.Student"/>

         <resultMap id="StudentResult" class="Student">

                   <resultproperty="sid" column="sid"/>

                   <resultproperty="sname" column="sname"/>

                   <resultproperty="major" column="major"/>

                   <resultproperty="birth" column="birth"/>

                   <resultproperty="sroce" column="sroce"/>

         </resultMap>

         <parameterMap id="StudentParameter" class=""Student"">

                 <parameterproperty="sid" jdbcType="int" javaType="int"/>

                 <parameterproperty="sname" jdbcType="varchar"javaType="String"/>

          </parameterMap>

         <select id="selectAllStudents" resultClass="Student" cacheModel=”product-cache”>

                   select

                            sid,sname,major,birth,score

                   from

                            student;

         </select>

         <select id="selectStudentById" parameterClass="int"resultClass="Student">

                   select

                            sid,sname,major,birth,score

                   from

                            student

                   where

                            sid= #sid#;

         </select>

        

         <insert id="insertStudent" parameterClass="Student">

                  insert into

                   student(sid,sname,major,birth,score)

                   values(#sid#,#sname#,#major#,#birth#,#score#);

         </insert>

        

         <delete id="deleteStudentById" parameterClass="int">

                   delete from

                            student

                   where

                            sid= #sid#;

         </delete>

         <update id="updateStudentById" parameterClass="student">

                   update student set

                   sname= #sname#,

                   major= #major#,

                   birth= #birth#,

                   score= #score#

                   wheresid = #sid#;

         </update>

<!-- 模糊查詢這裏有兩種方式,第一種在sql中這樣寫 sname like #sname#, 代碼中這樣寫"%e%" 第二種是在sql中sname like '%$sname$%',代碼中這樣寫"e".-->

         <select id="selectStudentByName" parameterClass="String"resultClass="Student">

                   select

                            sid,sname,major,birth,score

                   from

                            student

                   where

                            snamelike '%$sname$%';

         </select>

        

         <insert id="insertStudentBySequence" parameterClass="Student">

                   insert into

                   student(sname,major,birth,score)

                   values(#sname#,#major#,#birth#,#score#);

                   <!—Mysql中用到的-->

                    <selectKey resultClass="int"keyProperty="sid" >

            SELECT @@IDENTITY AS SID

        </selectKey>

                   <!--以下在Oracle中用到

                   <selectKey resultClass="int" keyProperty="sid">

                            select studentPKSequence.nextVal as sid from dual;

                   </selectKey>

                    -->

         </insert>

</sqlMap>

在這個例子中,xml的DTD和SqlMapConfig.xml配置文件的不一樣要注意,不然會報錯。例子中包括了cacheModel、typeAlias、resultMap、parameterMap、以及增刪改,查詢全部、根據id查詢和模糊查詢。其中增刪改查都屬於statement元素,下表總結了statement 類型及其屬性:

Statement 類型

屬性

<statement>

id

parameterClass

resultClass

parameterMap

resultMap

cacheModel

xmlResultName

<insert>

id

parameterClass

parameterMap

<update>

id

parameterClass

parameterMap

<delete>

id

parameterClass

parameterMap

<select>

id

parameterClass

resultClass

parameterMap

resultMap

cacheModel

<procedure>

id

parameterClass

resultClass

parameterMap

resultMap

xmlResultName

 

SQL 語句

在statement元素中可以寫所有JDBC Driver所支持的sql語句。但是由於sql語句是鑲嵌在xml文檔中,所以有些特殊符號不能直接使用,例如:<、>。iBatis這裏給出瞭解決辦法。

<![CDATA[

select * from student score >#score#

]]>

自動生成的主鍵

         iBatis中唯一使用了自動生成主鍵的就是<insert>元素,使用子元素<selectKey>來支持自動生成的主鍵。它同時支持預生成(如Oracle)和後生成(MySQL)。下面是兩個例子:

<!—OracleSEQUENCE Example -->

<insertid="insertStudent-ORACLE" parameterClass="com.edifier.Student">

<selectKey resultClass="int"keyProperty="id" >

SELECT STOCKIDSEQUENCE.NEXTVAL ASID FROM DUAL

</selectKey>

insert into Student (SID,SName)

values (#id#,#name#)

</insert>

<!—Microsoft SQL Server IDENTITY Column Example -->

<insert id=" insertStudent-MS-SQL" parameterClass="com. edifier. Student">

insert into Student ( SName)

values (#name #)

<selectKey resultClass="int"keyProperty="id" >

SELECT @@IDENTITY AS ID

</selectKey>

</insert>

存儲過程

通過<procedure>元素支持存儲過程。下面的例子說明如何使用具有輸出參數的存儲過程。

<parameterMapid="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>

<procedureid="swapEmailAddresses" parameterMap="swapParameters" >

{call swap_email_address (?, ?)}

</procedure>

調用上面的存儲過程將同時互換兩個字段(數據庫表)和參數對象(Map)中的兩個 email地址。如果參數的 mode 屬性設爲 INOUT 或 OUT,則參數對象的值被修改。否則保持不變。

parameterClass

parameterClass 屬性的值是 Java 類的全限定名(即包括類的包名)。parameterClass 屬性是可選的,但強烈建議使用。它的目的是限制輸入參數的類型爲指定的 Java 類,並優化框架的性能。如果您使用 parameterMap,則沒有必要使用 parameterClass 屬性。例如,如果要只允許 Java 類“com. edifier.Student”作爲輸入參數,可以這樣作:

<statementid=”statementName” parameterClass=” com. edifier.Student”>

insert into PRODUCT values (#id#, #name#, #score#)

</statement>

parameterMap

屬性 parameterMap 的值等於一個預先定義的<parameterMap>元素的名稱。parameterMap屬性很少使用,更多的是使用上面的 parameterClass 和 inline parameter(接下來會討論)。parameterMap 的基本思想是定義一系列有次序的參數系列,用於匹配 JDBC PreparedStatement的值符號。例如:

<parameterMapid=”insert-student -param” class=”com. edifier. Student”>

<parameter property=”id”/>

<parameter property=” name”/>

</parameterMap>

<statementid=”insertStudent” parameterMap=”insert- student -param”>

insert into Student (SID, SNAME) values(?,?);

</statement>

上面的例子中,parameter map 的兩個參數按次序匹配 SQL 語句中的值符號(?)。因此,第一個“?”號將被“id”屬性的值替換,而第二個“?”號將被“name”屬性的值替換。

Inline Parameter簡介

現在簡單介紹一下 inline parameter,詳細討論見後面章節。Inline parameter 可以嵌在

mappedstatement 內部使用。例如:

<statementid=”insertStudent” >

insert into Student(SID, SNAME)

values (#id#, #name#);

</statement>

以上例子中,內嵌的參數是#id#和#name#。每個參數代表一個 Java Bean 屬性,用於給 SQL 語句中相應的位置賦值。上面例子中,Student 對象的 id 和 description 屬性的值將會替換 SQL 語句中相應的符號。因此,對於 id=5,name=‘Steven’的Student 對象,SQL語句變爲:

insert into Student (SID, SNAME) values (5, ‘Steven’);

resultClass

         resultClass 屬性的值是 Java 類的全限定名(即包括類的包名)。resultClass 屬性可以讓您指定一個 Java 類,根據 ResultSetMetaData 將其自動映射到 JDBC 的 ResultSet。只要是 JavaBean 的屬性名稱和 ResultSet 的列名匹配,屬性自動賦值給列值。這使得查詢 mappedstatement變得很短。例如:

<statementid="getPerson" parameterClass=”int” resultClass="com.edifier.Person">

SELECT PER_ID as id,

PER_FIRST_NAME as firstName,

PER_LAST_NAME as lastName,

PER_BIRTH_DATE as birthDate,

PER_WEIGHT_KG as weightInKilograms,

PER_HEIGHT_M as heightInMeters

FROM PERSON

WHERE PER_ID = #value#

</statement>

在上面的例子中,Person 類擁有屬性包括 id,firstName,lastName,birthDate,weightInKilograms和 heightInMeters。每一個屬性對應 SQL 查詢語句一個列的別名(使用“as”關鍵字-標準的 SQL 語法)。一般情況下,列名和屬性名稱不匹配,就需要使用“as”關鍵字。當執行 mapped statement 時,Person 類將被初始化,從結果集中得到的列值將根據屬性名和列名映射成 Person 對象的屬性值。正如以前所說,使用 resultClass 的自動映射存在一些限制,無法指定輸出字段的數據類型(如果需要的話),無法自動裝入相關的數據(複雜屬性),並且因爲需要 ResultSetMetaData的信息,會對性能有輕微的不利影響。但使用 resultMap,這些限制都可以很容易解決。

resultMap

         resultMap 是最常用和最重要的屬性。ResultMap 屬性的值等於預先定義的 resultMap 元素的 name 屬性值(參照下面的例子)。使用 resultMap 可以控制數據如何從結果集中取出,以及哪一個屬性匹配哪一個字段。不象使用 resultClass 的自動映射方法,resultMap 屬性可以允許指定字段的數據類型,NULL 的替代值複雜類型映射(包括其他 Java Bean,集合類型和基本類型包裝類)。關於 resultMap 的詳細討論放在以後的章節,這裏只給出一個相關 statement 的 resultMap的例子。

<resultMapid=”get-student-result” class=”com.edifier.Student”>

<result property=”id” column=”SID”/>

<result property=”name” column=”SNAME”/>

</resultMap>

<statementid=”getStudent” resultMap=”get- student -result”>

select * from Student

</statement>

上面的例子中,通過 resultMap 的定義,查詢語句得到的 ResultSet 被映射成Student對象。resultMap 定義的“id”屬性值將賦予“SID”字段值,而“name”屬性值將賦予“SNAME”字段值。注意 resultMap 支持“select *”,並不要求定義 ResultSet所有返回字段的映射。

cacheModel

cacheModel 的屬性值等於指定的 cacheModel 元素的 name 屬性值。屬性 cacheModel 定義查詢 mapped statement 的緩存。每一個查詢 mapped statement 可以使用不同或相同的cacheModel。以下只給出個例子。

<cacheModelid="student-cache" imlementation="LRU">

<flushInterval hours="24"/>

<flushOnExecute statement="insertStudent"/>

<flushOnExecute statement="deleteStudentById"/>

<flushOnExecute statement="updateStudentById"/>

<property name=”size” value=”1000” />

</cacheModel>

<statementid=”selectAllStudent” parameterClass=”int” cacheModel=”product-cache”>

select sid,sname,major,birth,score from student;

</statement>

上面例子中,“selectAllStudent”的緩存使用 WEAK 引用類型,每 24 小時刷新一次,或當更新的操作發生時刷新。

Cache的類型有以下幾種

“MEMORY”(com.ibatis.db.sqlmap.cache.memory.MemoryCacheController)

“LRU”(com.ibatis.db.sqlmap.cache.lru.LruCacheController) --Least Recently Used

“FIFO”(com.ibatis.db.sqlmap.cache.fifo.FifoCacheController) --First In First Out

“OSCACHE”(com.ibatis.db.sqlmap.cache.oscache.OSCacheController)

1.MEMORY 編碼結構:

<cacheModel id="student-cache"type="MEMORY">

<flushInterval hours="24"/>

<flushOnExecute statement="insertStudent"/>

        <flushOnExecute statement="deleteStudentById"/>

<flushOnExecute statement="updateStudentById"/>

<property name=”reference-type”value=”WEAK” />

</cacheModel>

取不到對象再利用的identifiable pattern或者應用程序的內存不足的時候選用。

reference-type的值可以是下面的3個:

WEAK (default)

當別的對象要用內存的時候,可以毫無保留的釋放自己的內存。

SOFT

當別的對象需要內存的時候,有可能不會釋放自己的內存。

STRONG

cache時間到達以前,肯定不會釋放內存。小的靜態的經常被使用的區域可以使用這個選項。缺點是如果內存不足也不會釋放內存。

2.LRU 編碼結構:

<cacheModel id="student-cache"type="LRU">

<flushInterval hours="24"/>

<flushOnExecute statement="insertStudent"/>

        <flushOnExecute statement="deleteStudentById"/>

<flushOnExecute statement="updateStudentById"/>

<property name=”size” value=”1000” />

</cacheModel>

應用程序的一部分內容經常被多人多次使用的時候選用。

3.FIFO 編碼結構:

<cacheModel id="student-cache"type="FIFO">

<flushInterval hours="24"/>

<flushOnExecute statement="insertStudent"/>

         <flushOnExecute statement="deleteStudentById"/>

<flushOnExecute statement="updateStudentById"/>

<property name=”size” value=”1000” />

</cacheModel>

連續的短時間的參照,以後就再不參照的時候選用。

4.OSCACHE 編碼結構:

<cacheModel id="student-cache"type="OSCACHE">

<flushInterval hours="24"/>

<flushOnExecute statement="insertStudent"/>

<flushOnExecute statement="deleteStudentById"/>

<flushOnExecute statement="updateStudentById"/>

</cacheModel>

屬性名

說明

cache.memory

cache放在內存中,false的話放在硬盤裏

cache.key

ServletContext中存放cache的key名

cache.capacity

存放的大小(這個一直不知道單位是什麼,配置文件裏寫的是條數,我怎麼感覺設成50都能顯示1000個)

cache.path

cache保存的路徑

cache.unlimited.disk

無限cache,默認是false,這時候就會有限制,參照cache.capacity來分配硬盤空間

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章