MyBatis缓存配置

正确配置缓存能够提升系统的查询性能,这篇笔记我们以SpringBoot工程为例介绍MyBatis框架中和缓存相关的配置。

SqlSession缓存(一级缓存)

MyBatis的一级缓存和Hibernate类似,是SqlSession级别的缓存,且是默认启用的。我们开发者一般也不需要更改它的设置也感受不到它的存在,只要注意避免因缓存造成的bug即可(注:可能发生的bug是指查询得到的结果因缓存未得到及时更新,这个情况很难碰到)。

如果有必要,我们也可以指定强制刷新一级缓存,例子配置如下。

<select id="selectByid" flushCache="true" resultMap="userMap" >
  select * from sys user where id = #{id}
</select>

这样配置<select>标签后,每次查询都会刷新缓存,当然,这样做也会对性能产生影响。

基于EhCache实现二级缓存

除了一级缓存,MyBatis还具有内置的二级缓存功能。二级缓存是和命名空间(Mapper)绑定的,一个Mapper对应一组缓存,二级缓存可以在不同的SqlSession之间共享。二级缓存刷新时机主要依据如下判断:

  1. 针对Mapper执行了更新、插入、删除操作时,刷新缓存
  2. 根据<cache>中的设置刷新缓存

MyBatis框架内有一个默认的基于哈希表的二级缓存实现,但我们一般还是习惯于用EhCache等成熟的缓存框架作为底层的缓存实现。具体到MyBatis框架中,二级缓存需要实现org.apache.ibatis.cache.Cache接口的类,不过我们不必自己开发,MyBatis官方提供了和EhCache集成的库。下面例子中,我们引入了MyBatis集成EhCache的依赖。

<dependency>
    <groupId>org.mybatis.caches</groupId>
    <artifactId>mybatis-ehcache</artifactId>
    <version>1.1.0</version>
</dependency>

在SpringBoot工程中,我们可以配置mybatis.configuration.cache-enabledtrue开启二级缓存功能。

mybatis.configuration.cache-enabled=true

此外,在Mapper的映射XML中,我们还需要配置<cache>标签指定使用缓存。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.gacfox.demomb.dao.RoleMapper">
    <cache type="org.mybatis.caches.ehcache.EhcacheCache" eviction="LRU" size="1024" readOnly="false"/>
    <select id="selectAllRoles" resultType="com.gacfox.demomb.model.Role">
        select role_id as roleId, rolename
        from t_role
    </select>
</mapper>

<cache>标签有入下几个可配置选项:

  • type:缓存的提供类全名,比如使用EhCache这个值就是org.mybatis.caches.ehcache.EhcacheCache
  • eviction:缓存策略,如LRU(默认)FIFO等,都很好理解
  • size:缓存的引用数,默认1024个
  • readOnly:是否为只读缓存,默认为false,只读缓存使用Map会给调用者返回相同的实例,因此这些对象不能修改否则就容易出bug,可读写缓存会通过序列化返回缓存对象的拷贝,但也因此性能不如只读缓存。
  • flushInterval:缓存刷新时间,默认不定时刷新,只在调用语句时刷新

另外,我们的实体类还需要实现Serializable接口,以便对象能够存储到缓存系统中。

基于Redis实现二级缓存

如果想要基于Redis实现二级缓存,MyBatis并没有提供类似EhCache的mybatis-redis库(早年存在这个库但官方弃坑了),但编写一个兼容MyBatis的二级缓存组件也并不困难。

此外我们还有另一种选择,我们可以使用SpringCache库。SpringCache是一个Spring提供的声明式缓存管理组件,它没有和MyBatis直接集成,但它的功能允许我们将其和MyBatis结合使用,这部分可以参考SpringCache相关章节。

作者:Gacfox
版权声明:本网站为非盈利性质,文章如非特殊说明均为原创,版权遵循知识共享协议CC BY-NC-ND 4.0进行授权,转载必须署名,禁止用于商业目的或演绎修改后转载。
Copyright © 2017-2024 Gacfox All Rights Reserved.
Build with NextJS | Sitemap