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来分配硬盘空间

 

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