下面具体来看看resultMap的子元素
constructor: 用于在类构造函数中注入参数
idArg:ID 参数 用于提高整体性能
arg:普通参数
id:ID 结果
result:注入POJO属性的结果值
association:复杂的类型关联
collection:复杂类型集合
discriminator:根据结果值决定使用哪个resultMap
case:判断条件
id,result:
<id property="id" column="post_id"/>
<result property="subject" column="post_subject"/>
id,result均将单个列的值映射到POJO中的单个简单类型属性(如int,double,Date等等)
id映射主键,result映射普通属性
属性 | 描述 |
property | POJO中对应的属性 |
column | 数据库中列名 |
javaType | java类型 |
jdbcType | jdbc类型 遇到空值时需要显示指明 |
typeHandler | 类型转换器 |
支持的jdbcTypes
BIT | FLOAT | CHAR | TIMESTAMP | OTHER | UNDEFINED |
TINYINT | REAL | VARCHAR | BINARY | BLOB | NVARCHAR |
SMALLINT | DOUBLE | LONGVARCHAR | VARBINARY | CLOB | NCHAR |
INTEGER | NUMBERIC | DATE | LONGVARBINARY | BOOLEAN | NCLOB |
BIGINT | DECIMAL | TIME | NULL | CURSOR | |
为了实现这种注入,ibatis需要表明构造函数的各个参数类型,正如上面的xml代码段所示。保证配置参数按照构造函数中参数的顺序进行配置参数类型
属性 | 描述 |
column | 数据库中列名 |
javaType | java类型 |
jdbcType | jdbc类型 遇到空值时需要显示指明 |
typeHandler | 类型转换器 |
association:<association property="author" column="blog_author_id" javaType=" Author">
<id property="id" column="author_id"/>
<result property="username" column="author_username"/>
association>
association标签定义了实体之间的关联,比如blog拥有一个作者属性,那么这来两个实体之间就可以用上面那个关系来定义。
属性 | 描述 |
property | 列映射的POJO属性 |
column | 关联的列名 |
javaType | java类型 |
jdbcType | jdbc类型 遇到空值时需要显示指明 |
typeHandler | 类型转换器 |
ibatis有两种加载关联关系的方法:
Nested Select:
属性 | 描述 |
select | 另一个加载数据的sql语句id |
例如:
<resultMap id=”blogResult” type=”Blog”>
<association property="author" column="blog_author_id" javaType="Author"
select=”selectAuthor”/>
resultMap>
<select id=”selectBlog” parameterType=”int” resultMap=”blogResult”>
SELECT * FROM BLOG WHERE ID = #{id}
select>
<select id=”selectAuthor” parameterType=”int” resultType="Author">
SELECT * FROM AUTHOR WHERE ID = #{id}
select>
在这里我们有两个select语句,一个去加载blog数据,另一个去加载author数据,在blog定义的resultMap中使用了加载author的select语句,对blog中的author属性进行赋值。也就是说,这种简单的一对一关系,执行了两条select语句。
使用nested select会产生“N+1”问题,非常常见,性能消耗相当大,可以使用懒加载来解决,或者使用下面一种方法。
Nested Result:
属性 | 描述 |
resultMap | 映射关联属性字段的resultMap id值,采用join的方式一次查询得出结果 |
例如:
<resultMap id="blogResult" type="Blog">
<id property=”blog_id” column="id" />
<result property="title" column="blog_title"/>
<association property="author" column="blog_author_id" javaType="Author"
resultMap=”authorResult”/>
resultMap>
<resultMap id="authorResult" type="Author">
<id property="id" column="author_id"/>
<result property="username" column="author_username"/>
<result property="password" column="author_password"/>
<result property="email" column="author_email"/>
<result property="bio" column="author_bio"/>
resultMap>
或者:
在select语句中使用:
<select id="selectBlog" parameterType="int" resultMap="blogResult">
select
B.id as blog_id,
B.title as blog_title,
B.author_id as blog_author_id,
A.id as author_id,
A.username as author_username,
A.password as author_password,
A.email as author_email,
A.bio as author_bio
from Blog B left outer join Author A on B.author_id = A.id
where B.id = #{id}
select>
collection:
collection元素的关联加载
Nested select for Collection:
discriminator:
有时候我们从数据库中得到的值不仅仅对应一种POJO,可能根据参数不同对应不懂的POJO,如车辆的属性根据卡车、汽车而不同,那么可以使用以下配置
cache:ibatis中可以使用cache提高效率,默认不开启cache配置,需要使用标签,其默认含义为:
所有select语句返回的数据将被缓存
insert update delete语句将会强制输出缓存
使用LRU算法
没有强制输出的周期(No Flush Interval)
缓存区大小为1024条记录或者对象的引用
可读写的缓存,缓存中的数据可以被调用它的函数修改
也可以手动设置这些配置属性,例如:
<cache
eviction="FIFO"
flushInterval="60000"
size="512"
readOnly="true"/>
上面的配置说明了使用FIFO缓存机制,每60秒输出一次缓存,缓存区大小为512,缓存中的数据是只读的。
缓存过期算法:
LRU 最近最少使用
FIFO 先进先出
SOFT 只有当目前内存不足的情况下,JVM 在垃圾回收时才会收回其包含的引用
WEAK 只要JVM 启动了垃圾回收机制,那么WeakReference 所对应的对象就将被JVM 回收
cache的使用机制和sql Map File的命名空间是绑定的。
也可以自定义cache来使用,这个还没怎么搞懂,先放放。先根据上面一些内容跑个一对一、一对多的例子起来,这里太多了,放下一篇吧。
作者:少帅