`
kidiaoer
  • 浏览: 810935 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

ibatis总结

阅读更多
1.   IBatis简介
IBatis是以SQL为中心的持久化层框架,是一种“半自动化”的ORM实现。

IBatis不但提供了对象与关系数据库之间的映射,同时提供操作方法与SQL间的直接映射,设计者可以直接为一个方法指定一条SQL语句,从而取得更加准确的数据。因为 IBatis 的 sql 都保存到单独的xml文件中,有利于DBA对 sql 的 审核和优化。IBatis最大的特点就是小巧,上手很快,可维护性较好。

IBatis数据映射的工作流程图如图1所示:


图1:IBatis数据映射的工作流程图

2.   使用步骤
2.1 SQL Map 配置文件
SQL Map 配置文件中对<properties>、< settings >、< typeAlias >、< transactionManager >、< dataSource >、< sqlMap >等进行配置。

2.2 SQL Map映射文件
和 "IBatis总结" 有关的 java 编程小帖士:

strong>DataFormats.Format.win32Handle

指定一个boolean值,此值决定这个格式是否期望Win32句柄。

语法

public final boolean win32Handle;

构造器
 
在SQL Map映射文件中,可以定义的Statement 类型有<statement>、<insert>、<update>、<delete>、<select>、<procedure>。

      可以使用缓存模式,Cache的3个重要属性是readOnly、serialize和type;Cache类型分为MEMORY、LRU、FIFO、OSCACHE四种。

2.3编写DAO 
在DAO中,可以使用SqlMapClient提供的方法执行sql操作。

 

3.   开发过程中的注意点
1. 对Sequence主键,插入语句之前必须指定一个主键值给要插入的记录,否则无法插入。方法是在插入语句标签<insert....>之前配置上:

  <insert id="addItemDO" parameterClass="TryItem">

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

        select ITEM_ID.nextval as value from dual

    </selectKey>

            insert into item …

</insert>

 

2. 通过使用<![CDATA[……]]>,可以避免SQL 中与XML 规范相冲突的字符,如<=,>=,<,>

 

3. 模糊查询中参数的引用,应使用$,而不是#,比如:'%$varName$%',或者 '%' || #varname# || '%'。例子:TITLE like '%' || #keyWord# || '%'

 

4. SQL入参parameterClass.SQL中引用parameterClass的参数有三种方式:

IBatis内置支持的类型,比如int、string,使用#value#来引用,这个value是关键字,不可变。

map类型的参数,使用#keyName#来引用,keyName为键名。

复杂对象的参数,使用#propertyName#来引用,propertyName类属性的名字。

IBatis仅接受一个入参,当几个参数分布在不同对象中的时候,将这些对象的属性(或者对象本身put)到map中,然后一次传递给sql语句是非常有效。例如parameterClass="java.util.Map"

 

5. 返回值参数类型: 一种是对象类型resultClass="int",一种是resultMap=" ItemResultMap "。当查询结果列名和类属性名对应不上的时候,应该选择resultMap指定查询结果集类型。否则查询出来填充的对象属性为空(数字的为0,对象的为null)。

 

6. 动态SQL。prepend表示链接关键字,可以为任何字符串,当为sql关键字时,IBatis自动判断是否应该添加该关键字。

例子:一个动态的where条件

<dynamic prepend="WHERE">

                 <isNotNull property="skin" prepend="and">

                   t.skin=#skin# 

                 </isNotNull>

                 <isNotNull property="effi" prepend="and">

                   t.effect=#effi# 

                 </isNotNull>             

</dynamic>

 

7. 不能自动识别null,就是匹配的字段不能为null,要么就必须为其设置当是null时的默认值。






标签: ibatis  2009-04-08 00:11parameterClass指定参数的全限定类名称; 
parameterMap定义一系列有次序的参数系列,用于匹配JDBC PreparedStatement的值符;例如:
<parameterMap id=”insert-product-param” class=”com.domain.Product”>
    <parameter property=”id”/>
    <parameter property=”description”/>
</parameterMap>


<statement id=”insertProduct” parameterMap=”insert-product-param”>
    insert into PRODUCT (PRD_ID, PRD_DESCRIPTION) values (?,?);
</statement>

 3. 大于号,小于号的解决方法:

<statement id="getPersonsByAge" parameterClass=”int” resultClass="examples.domain.Person">
<![CDATA[

SELECT *
FROM PERSON
WHERE AGE > #value#


]]>
</statement>

  4. resultClass属性可以让您指定一个Java类,根据ResultSetMetaData将其自动
  映射到JDBC的ResultSet。只要是Java Bean的属性名称和ResultSet的列名匹配,
  属性自动赋值给列值,。一般情况下,列名和属性名称不匹配,就需要使用“as”关键字。

<statement id="getPerson" parameterClass=”int” resultClass="examples.domain.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>

    使用resultClass的自动映射存在一些限制,无法指定输出字段的数据类型(如果需要的话),无法
	自动装入相关的数据(复杂属性),并且因为需要ResultSetMetaData的信息,会对性能有轻微的不
	利影响。但使用resultMap,这些限制都可以很容易解决。

5.resultMap字段:准确匹配字段;不要求定义ResultSet所有返回字段的映射。

<resultMap id=”get-product-result” class=”com.ibatis.example.Product”>
    <result property=”id” column=”PRD_ID”/>
    <result property=”description” column=”PRD_DESCRIPTION”/>
</resultMap>


<statement id=”getProduct” resultMap=”get-product-result”>
    select * from PRODUCT
</statement>

6.cacheModel
cacheModel的属性值等于指定的cacheModel元素的name属性值。属性cacheModel定义查询mapped statement的
缓存。每一个查询mapped statement可以使用不同或相同的cacheModel。
<cacheModel id="product-cache" imlementation="LRU">
    <flushInterval hours="24"/>
    <flushOnExecute statement="insertProduct"/>
    <flushOnExecute statement="updateProduct"/>
    <flushOnExecute statement="deleteProduct"/>
    <property name=”size” value=”1000” />
</cacheModel>
<statement id=”getProductList” parameterClass=”int” cacheModel=”product-cache”>
select * from PRODUCT where PRD_CAT_ID = #value#

上面例子中,“getProductList”的缓存使用WEAK引用类型,每24小时刷新一次,或当更新的操作发生时刷新。

7.xmlResultName
当直接把查询结果映射成XML document时,属性xmlResultName的值等于XML document根元素的名称。例如:
<select id="getPerson" parameterClass=”int” resultClass="xml" xmlResultName=”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#
</select>
上面的查询结果将产生一个XML document,结构如下:
<person>
    <id>1</id>
    <firstName>Clinton</firstName>
    <lastName>Begin</lastName>
    <birthDate>1900-01-01</birthDate>
    <weightInKilograms>89</weightInKilograms>
    <heightInMeters>1.77</heightInMeters>
</person>

8. 解决int字段默认为0,而数据库中的字段为null的问题:

<parameterMap class="User" id="UserNameAndBirthday">
   <parameter property="name"/>
   <parameter property="money" jdbcType="INTEGER" nullValue="0"/>
</parameterMap>

9.extend关键字可用于联合查询,数据表之间不需要有继承关系。

10. 重要说明:sqlmap文件中互相引用的时候是有顺序的,比如在sqlmapconfig中加载sqlmap文
件的顺序是sqlmapA->sqlmapB,如果在sqlmapB中指定一个<select>的resultMap为sqlmapA.AResult,没
问题。反之如果在A中引用B的sqlmapB.BResult,则会报错。所以定义resultMap的common.xml一定要在
所有的sqlmap之前!

11. N+1 问题描述:当一个表有1个外键的时候,查询这个表的信息时,如果不用外连接或者联合查询,那么
要用额外的一条SQL来查询外键所连接的表的信息。解决方法就是联合查询或者连接查询(用一条SQL来解决问题)。

12. 在一对多的映射关系中,ibatis一定会出现N+1问题;

13. 缓存管理

“MEMORY” (com.ibatis.db.sqlmap.cache.memory.MemoryCacheController)MEMORY cache实现使
用reference类型来管理cache的行为。垃圾收集器可以根据reference类型判断是否要回收cache中
的数据。MEMORY实现适用于没有统一的对象重用模式的应用,或内存不足的应用。
<cacheModel id="product-cache" type="MEMORY">
<flushInterval hours="24"/>
<flushOnExecute statement="insertProduct"/>
<flushOnExecute statement="updateProduct"/>
<flushOnExecute statement="deleteProduct"/>
<property name=”reference-type” value=”WEAK” />
</cacheModel>。这个名为“reference-type”属性的值必须是STRONG,SOFT和WEAK三
者其一;WEAK:大多数情况下,WEAK类型是最佳选择。如果不指定类型,缺省类型就
是WEAK。它能大大提高常用查询的性能。但是对于当前不被使用的查询结果数据,将
被清除以释放内存用来分配其他对象。SOFT:在查询结果对象数据不被使用,同时需要
内存分配其他对象的情况下,SOFT类型将减少内存不足的可能性。然而,这不是最具
侵入性的reference类型,结果数据依然可能被清除。STRONG:此类型可以确保查询结
果数据一直保留在内存中,除非Cache被刷新(例如,到了刷新的时间或执行了更新
数据的操作)。对于下面的情况,这是理想的选择:
1)结果内容数据很少,
2)完全静态的数据,和3)频繁使用的数据。优点是对于这类查询性能非常好。
缺点是,如果需要分配其他对象,内存无法释放(可能是更重要的数据对象)。 
“LRU” (com.ibatis.db.sqlmap.cache.lru.LruCacheController)
LRU Cache实现用“近期最少使用”原则来确定如何从Cache中清除对象。当Cache溢出
时,最近最少使用的对象将被从Cache中清除。使用这种方法,如果一个特定的对象
总是被使用,它将保留在Cache中,而且被清除的可能性最小。对于在较长的期间内,某些
用户经常使用某些特定对象的情况(例如,在PaginatedList和常用的查询关键字结果集中
翻页),LRU Cache是一个不错的选择。LRU Cache实现可以这样配置:
<cacheModel id="product-cache" type="LRU">
   <flushInterval hours="24"/>
   <flushOnExecute statement="insertProduct"/>
   <flushOnExecute statement="updateProduct"/>
   <flushOnExecute statement="deleteProduct"/>
   <property name=”size” value=”1000” />
</cacheModel>


















分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics