MyBatis 使用 J2Cache 作为二级缓存实现
大纲
J2Cache 的 Gradle 配置
在项目中引入以下依赖后,需要根据项目具体的运行状况调整 Gradle 的依赖配置,以下配置使用到 SpringBoot。
1 | compile 'net.oschina.j2cache:j2cache-core:2.7.6-release' |
MyBatis 使用 J2Cache
首先在 MyBatis 的全局配置文件中开启二级缓存,然后根据下面的两种情况进行配置(二选一)
1 | <settings> |
第一种使用情况:对当前 namespace 内的所有 SQL 启用二级缓存
1 | <mapper namespace="com.example.dao.user.UserApiMapper"> |
或者使用 Java 注解进行配置,此写法会导致 XML 映射文件中的其他 SQL 无法使用二级缓存,下面会详细介绍
1 |
|
第二种使用情况:对当前 namespace 内指定的 SQL 设置是否启用二级缓存
1 | <mapper namespace="com.example.dao.user.UserApiMapper"> |
或者使用 Java 注解进行配置,此写法会导致 XML 映射文件中的其他 SQL 无法使用二级缓存,下面会详细介绍
1 |
|
J2Cache 的使用注意事项
MyBatis-Plus 二级缓存不生效
官方推荐使用的方式是统一在 XML 映射文件中配置缓存与 SQL,此方式在 MyBatis + MyBatis-Plus(version <= 2.0.9)的环境下可以正常工作。但是当使用版本号大于 2.0.9 的 MyBatis-Plus,使用 XML 配置缓存的方式会导致 MyBatis-Plus 的二级缓存不生效,具体表现为发出的 SQL(由 MyBatis-Plus 自动生成的 SQL)不能正常使用二级缓存。根据 MyBatis-Plus 官方文档的说明,当使用 2.0.9 以上的版本,需要在代码中 MyBatis 的 Mapper 层添加缓存注释 @CacheNamespace
,并声明 implementation
属性的值为 Cache 接口的实现类,此时 XML 映射文件中不能再声明 cache 标签,代码如下:
1 |
|
MyBatis 二级缓存不生效
使用 @CacheNamespace
注解后,MyBatis-Plus 的二级缓存确实是生效了,但在 XML 映射文件中的其他 SQL 此时不能正常使用二级缓存,而在 Mapper 接口里通过注解声明的 SQL 则不受影响。
二级缓存使用总结
不管通过注解还是 XML 的方式配置缓存,总结大概有以下几种使用情况。实际开发中可以根据不同的业务需求混合使用不同的配置方式。第一种方式适合 SQL 比较复杂的业务场景,第三种方式适合 SQL 比较简单的业务场景,推荐使用第一种方式。
- 第一种:MyBatis 单独正常使用二级缓存,将所有 SQL、缓存配置都写在 XML 映射文件中,此时 MyBatis-Plus 的二级缓存失效;
- 第二种:MyBatis-Plus 正常使用二级缓存,在 Mapper 接口里声明注解
@CacheNamespace
,此时 MyBatis 的二级缓存失效(针对 XML 中定义的 SQL),而 MyBatis 通过 Java 注解定义的 SQL 则依然会生效; - 第三种:MyBatis 与 MyBatis-Plus 同时正常使用二级缓存,将所有 SQL、缓存配置通过注解的方式定义在 Mapper 层;此时 XML 映射文件中不能再定义 SQL,否则 XML 中的 SQL 无法使用二级缓存。
J2Cache 配置文件的使用
J2Cache 支持使用 Redis 或者 RabbitMQ 的 Pub/Sub 服务,支持使用 Ehcache、Caffeine 作为一级缓存,支持使用 Jedis、Lettuce 作为 Redis 的客户端。目前 J2Cache 最主要的配置内容只能写在 j2cache.properties
文件中,如果将配置内容全部移动到 SpringBoot 的 xxx.yml
文件中,SpringBoot 应用的启动与单元测试都会出错,这与 J2Cache 的源码有关。
基于 SpringBoot 的单元测试类
当 MyBatis 的 Mapper 使用 J2Cache 作为二级缓存的实现,那么单元测试类中暂时需要指定 J2Cache 的相关配置,否则测试类无法正常启动。如果每个测试类都要加上一堆 J2Cache 的配置内容,实在是不方便,而且 J2Cache 的配置一旦更改,则需要修改每个测试类的代码。为了解决这种情况,可以在模块下创建 BaseSpringBootTest 基础测试类,然后其他测试类直接继承基础测试类即可。
1 | /** |
临时关闭 MyBatis 使用 J2Cache
在 MyBatis 的全局配置文件中,关闭二级缓存即可,如下所示:
1 | <settings> |
指定 J2Cache 的缓存大小与有效时间
当 J2Cache 作为 MyBatis 的二级缓存实现,J2Cache 官方支持在配置文件中指定缓存的大小与有效时间,具体配置如下:
1 | # redis storage mode (generic|hash) |
重点关注的配置是 caffeine.region.default
,上面配置了默认 Region(区域)的一级缓存大小为 1000,有效时间为 30 分钟。举个例子,如果需要为 UserAPI 表的记录单独设置缓存大小和有效时间,可以参考以下配置;其中 Region 是 Mapper 的类全名,大小为 2000,有效时间为 12 小时。当 J2Cache 找不到对应的 Region,默认会采用 caffeine.region.default
的配置策略,如下所示:
1 | caffeine.region.com.example.dao.user.UserApiMapper = 2000, 12h |