缓存是将数据保存到内存中,在读取的时候无需从磁盘读入,具备快速读取和使用的优点,缓存的关键在于缓存的命中率,命中率高就能极大提升系统性能,命中率低则不存在使用的意义。
默认开启一级缓存
一级缓存是在SqlSession层面上的,多个SqlSession之间不共享,SqlSession调用Mapper接口执行Sql语句查询时,会进行缓存,当第二次用相同的SqlSession调用相同的Mapper接口执行相同的Sql查询语句时,会从缓存中获取,而不发送Sql到数据库。当然,读取缓存的前提是缓存没有过期,而且缓存没有被刷新
二级缓存要手动开启,方式为XML文件配置<cache/>
,二级缓存存在的原因是多个SqlSession之间是隔离的,一级缓存不能共享,二级缓存就是为了实现SqlSession之间可以共享缓存,二级缓存即在SqlSessionFactory层面上的。其次,二次缓存要求返回的POJO是可以序列化的,要实现Serializable接口。
当使用二级缓存的时候,sqlSession调用commit方法后才会生效。
<cache/>
配置中包含了很多默认配置。单独<cache/>
配置,意味着:
- 映射语句文件的所有的select语句都会被缓存
- 映射语句文件中所有的insert、update、delete语句都会刷新缓存
- 缓存会使用默认的LRU算法来淘汰部分缓存
- 根据时间表,例如No Flush Interval,(CNFI,没有刷新间隔),缓存不会以任何时间顺序来刷新
- 缓存会存储列表集合或对象(无论查询方法返回什么)的1024个引用
- 缓存会被视为read/write(可读可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,不干扰其他调用者或者线程所做的潜在修改
<cache/>
配置的修改
<cache eviction="LRU" readOnly="true" size="512" flushInterval="60000"/>
eviction:代表缓存回收策略,支持LRU,FIFO,SOFT,WEAK
flushInterval:刷新缓存间隔时间,单位为毫秒,如果不配置,则当SQL执行的时候才会刷新缓存
自定义缓存,一级和二级缓存都是系统缓存,系统缓存是mybatis缓存在本地机器。定制缓存可以使用各类不同的缓存服务器,实现org.apache.ibatis.cache接口即可。
还可以在SQL语句层面上配置缓存规则,来决定sql语句是否使用缓存和刷新缓存,两个重要属性:useCache和flushCache,在mapper配置文件中的sql语句元素中配置
<select id="" flushCache="false" useCache="true"/> <delete id="" flushCache="true"/>
查询语句才会使用缓存,其他语句不会,但是可以刷新缓存