缓存不是基于行的
“缓存并不是基于行的”的意思就是,mybatis缓存的粒度是全部查询结果,而不是查询结果的每行,这也就意味着每次查询,就只有一份缓存,而不是有几行就有几分缓存。
这点和hibernate很不同,hibernate的缓存是基于每个对象的,即查询出来的有几个对象,那就有几份缓存。
mybatis无法像hibernate给每个对象做缓存,主要原因是mybatis非常自由,能够配置任意的返回结果类型,这也就是说返回的结果并不一定都有主键,如此一来也就没有办法标识某一行数据和哪个返回结果对应,而hibernate是强制你所映射的每个类都要有主键的。
参考文档:http://www.mybatis.org/mybati...
缓存默认没有失效时间
“缓存默认没有失效时间”的意思是如果我们直接在数据库里修改数据,那么每次用mybatis查询的时候,使用的还是上一次的缓存结果,且这份缓存一直有效,除非我们通过mapper调用了update、delete、insert方法,这些方法会使缓存失效。解决办法很简单,就是在使用<cache />
的时候一定要写上flushInterval
属性。
参考文档:http://www.mybatis.org/mybati...
使用Partial Auto-mapping后,自动去重问题
Partial Auto-mapping的意思是你对ResultMap只提供了部分字段的配置而不是全部字段,但是如果你的这个ResultMap没有设置ID,也就是主键,那么mybatis将会根据你提供的这一部分字段配置来判断两行数据是否重复,并且会将重复的去掉。
实际上关于id的作用在官方文档中很隐晦的提到过了:见id & result。
比如下面这个配置启用了autoMapping
,且部分配置了property的映射。在这种情况下,如果查询出两条记录了,而这两条记录的task_key
的值是一样的时候,mybatis就会认为是同一条,最终返回给你一个AuditLog
。
<resultMap id="AuditLog" type="AuditLog" autoMapping="true">
<result column="task_key" property="taskKey"/>
</resultMap>
解决办法有两个:
-
不配置property的映射:
<resultMap id="AuditLog" type="AuditLog" autoMapping="true"> </resultMap>
-
不使用automapping:
<resultMap id="AuditLog" type="AuditLog"> <result column="task_key" property="taskKey"/> <result column="result" property="result"/> <result column="when" property="when"/> <result column="name_zh" property="nameZh"/> <result column="name_en" property="nameEn"/> <result column="remark" property="remark"/> </resultMap>
参考文档:http://www.mybatis.org/mybati...
aggressiveFetch的问题
在使用mybatis懒加载特性的时候有一点需要注意,就是要把aggressiveFetch
设置为false
。
根据官方文档,当设置为true的时候,如果你get了懒加载属性,那么其他懒加载属性也会一并加载。
但实际情况时,当设置了true的时候,如果你get了任一属性,那么所有懒加载属性也会一并加载。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。