前一阵一直在看iBatis,也准备将其引入项目的开发中,感觉由于使用直接sql映射对象的方式,对于熟悉sql的人来说上手十分方便。这里整理了一下学习中的心得,iBatis的文档还是十分不错的,而且还有中文版,这个在开源工具中真是不多见的,但愿以后这样的情况能越来越多:)
一、Statement
1、 Mapped Statement的id是全局的,在各个xml文件内都可以直接使用。
二、parameter
1、 parameterMap 一般可用parameterClass和inline parameter替代,此外动态Mapped Statement只支持inline parameter
其中:
jdbcType 在字段可以为Null时才需要。在orcale中,若没有设置,插入null会报错。
插入的jdbcType可参考java.sql.Type中定义的类型名称。
parameterMap的名称是局部的,在其他xml文件中引用,必须以“前缀.名称”的形式
2、 parameterClass建议使用,可优化框架性能。Class的值需是全限定的java类名
3、 使用parameterMap与prarmeterClass的区别:parameterMap允许null的替换值
4、 inline parameter 更灵活,可简化定义与代码量。
在内嵌参数中,可以指定parameterMap中有的所有属性。此外,在需要指定null的替换值时,必须先指定jdbcType。
insert into category(CATID, NAME, DESCN)
values(#categoryId#,#name#,#description:VARCHAR#)
需要指定很多字段的时候,可以使用外部parameterMap,这样可使代码更清晰
三、result
1、resultClass 只要JavaBean的属性名与字段名相同,自动匹配。
限制:
1) 无法指定字段的数据类型
2) 无法自动转入相关数据(复杂类型、1:n、n:m)
2、 resultMap 最常用与最重要的属性
1) columnIndex: 在某些jdbcType driver的情况下可提高性能
jdbcType : resultMap没有null值问题,但是用来作为数据映射类型只用(如:将Sting——>Varchar、char、blob等)
javaType : 一般用于指定转换到map和xml的类型映射
select : 用于描述对象间关系(1:1,1:m)
2) 隐式resultMap 即只用resultClass,一般用于简单的映射关系。
缺点:
无法指定字段的数据类型
无法指定null值替代
对于Bean中属性大小写不敏感(由于数据库本身就不是大小写敏感的)
此外,resultClass的自动映射会影响性能(轻微)
3) Re’sultMap的名称是局部的
4) Map类型的result,在resultMap定义只类名写成java.util.HashMap
四、复杂类型(1:N,N:M)
1、复杂类型集合的属性(JavaBean中的属性)必须是java.util.Lst或java.util.Collection。只能使用这2个接口,因为iBatis内部使用的是动态代理。
2、使用延迟加载和字节码增强来优化查询,对于1:1的,可以使用联合查询来替代
3、对于1:M、N:M的性能问题,没有很好的解决办法,在性能要求比较高时,考虑少用。
4、对于1:M的xml:
Resultmap的设置
id= "result" class= "exsample.dao.domain.Category" >
property= "categoryId" column= "catid" />
property= "name" column= "name" />
property= "description" column= "descn" />
property= "productList" column= "catid" select= "getProductsByCategoryId" />
Select的设置
id= "getProduct" resultMap= "result" >
select productid, name, descn, category from product where productid = #value#
五、缓存
1、只读缓存,可让多用户共享,性能更好
2、Serializble可读写缓存,不能与延迟缓存同时使用,因为延迟加载代理是不支持Serializble的
3、缓存类型
类型 |
说明 |
Memory |
缺省week。 能打打提高常用查询的性能 用jvm中内存管理的可达性模型,数据可能垃圾收集器清除,不会造成内存不足。 |
Lru |
不要cache太多对象,可能会造成内存不足。 |
Fifo |
|
OSCACHE |
第三方包,功能强大,需自己配置 |
六、动态Mapped Statement
1、Iterator与$……$ 连用可以自动实现很多复杂的sql
2、对于Iterator的传入参数,在sql中需要写成#value[]#的形式
3、在sql中#……#用于带入sql中的参数,$……$用于带入sql中的关键字、字段名等
id= "getProductsByLike" resultMap= "result" >
select productid, name, descn, category from product
prepend= "where" >
prepend= "and" property= "productIdList" open= "(" close= ")" conjunction= "OR" >
productid = #productIdList[]#
prepend= "and" property= "descList" open= "(" close= ")" conjunction= "OR" >
descn $operator$ #descList[]#
3、 若要直接生成全部的sql,可以使用如下形式:
id= "getProductsBySQL" resultClass= "java.util.HashMap" >
$value$
其中value为传入的sql
返回result,可以是map,若没有做resultMap映射,则返回的字段在map中的键值都为大写。