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>
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值