动态SQL<br>
trim|where|set|foreach|if|choose|when|otherwise|bind
分页
分页方式
使用RowBounds对象进行内存分页(假分页)
分页原理
用Mybatis提供的插件接口,<br>实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。<br>
mybatis支持插件<br>
<b><font color="#f68b1f">可以编写针对<u>ParameterHandler</u>、<u>ResultSetHandler</u>、<u>StatementHandler</u>、<u>Executor</u>这4种接口的插件</font></b>
缓存
一级缓存
会话级缓存,会话结束即清空<br>
<b style="font-size: inherit;"><font color="#f15a23">对其他session对数据的CUD操作无法感知</font></b><br>
基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session<br>
是一个粗粒度的缓存,没有更新缓存和缓存过期的概念,同时只是<b>使用了默认的hashmap</b>,也<b>没有做容量上的限定</b>
对统一SQL的认定Key为:Statement Id + Offset + Limmit + Sql + Params
有<b>多个SqlSession或者分布式的环境下,有操作数据库写的话,会引起脏数据,</b>建议是把一级缓存的默认级别设定为Statement,即不使用一级缓存<br>
二级缓存
存储作用域为 <font color="#f68b1f"><b>Mapper(Namespace)</b></font>
默认不打开二级缓存
使用<font color="#c41230">二级缓存属性<b><u>类需要实现Serializable序列化接口(可用来保存对象的状态)</u></b>,</font>可在它的映射文件中配置、<b><cache/> </b>;
多表查询时,极大可能会出现脏数据,有设计上的缺陷,安全使用的条件比较苛刻
分布式环境下必然会出现读取到脏数据,需要使用集中式缓存将Mybatis的Cache接口实现,有一定的开发成本,不如直接用Redis,Memcache实现业务上的缓存就好了。
注意事项及解决办法
由于二级缓存基于namespace缓存,如果在另外一个namespace更改了数据是无法感知的,因此建议在同一个namespace下处理CRUD。<br>解决办法:<br><b><font color="#f68b1f"><cache-ref namespace="*。*。*Mapper"/><br>cache-ref代表引用别的命名空间的Cache配置,两个命名空间的操作使用的是同一个Cache。不过这样做会使缓存粒度变粗,如果关联较多就失去了缓存的意义。</font></b><br>
更新机制<br>
<b><font color="#f68b1f">当某一作用于进行CUD操作后,其下所有select缓存清空</font></b>
数据的查询执行的流程就是 <font color="#f68b1f">二级缓存 -> 一级缓存 -> 数据库</font>。