SpringBoot系列之使用Redis做Mybatis二级缓存
Posted smileNicky
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SpringBoot系列之使用Redis做Mybatis二级缓存相关的知识,希望对你有一定的参考价值。
开发环境
- JDK 1.8
- SpringBoot2.2.1
- MybatisPlus3.4.3.4
- Maven 3.2+
- mysql5.7.36
- 开发工具
- IntelliJ IDEA
- smartGit
使用阿里的脚手架,链接:https://start.aliyun.com
选择mybatis plus framework
然后项目基础架构搭建好之后,加上redis配置
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
加上redis配置:
spring:
redis:
host: 127.0.0.1
port: 6379
password:
database: 0
MyBatisPlus开启缓存支持
实现Cache
接口,因为这个类不是Spring管理的,所以通过SpringContextHolder
从ioc容器里获取redisTemplate类
package com.example.mybatisplus.common.cache;
import com.example.mybatisplus.common.ioc.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
@Slf4j
public class MyBatisRedisCache implements Cache
private static RedisTemplate<String , Object> redisTemplate;
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
private String id;
public MyBatisRedisCache(String id)
if (StringUtils.isEmpty(id))
throw new IllegalArgumentException("cache instances require an id.");
this.id = id;
if (redisTemplate == null)
redisTemplate = SpringContextHolder.getBean("redisTemplate");
@Override
public String getId()
return this.id;
@Override
public void putObject(Object key, Object value)
if (!StringUtils.isEmpty(value))
redisTemplate.opsForHash().put(id, key.toString() , value);
log.info("mybatis缓存,:[]" , key , value );
@Override
public Object getObject(Object key)
if (!StringUtils.isEmpty(key))
Object object = redisTemplate.opsForHash().get(id , key.toString());
log.info("mybatis缓存读取,:[]", key , object);
return object;
return null;
@Override
public Object removeObject(Object key)
if (!StringUtils.isEmpty(key))
redisTemplate.delete(key.toString());
return null;
@Override
public void clear()
redisTemplate.delete(id.toString());
@Override
public int getSize()
return redisTemplate.opsForHash().size(id.toString()).intValue();
@Override
public ReadWriteLock getReadWriteLock()
return readWriteLock;
修改CacheNamespace
指定缓存类,implementation
属性:默认是PerpetualCache
类,即hashMap
实现
package com.example.mybatisplus.mapper;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplus.common.cache.MyBatisRedisCache;
import com.example.mybatisplus.model.User;
import org.apache.ibatis.annotations.CacheNamespace;
@DS(value = "shop")
@CacheNamespace(implementation = MyBatisRedisCache.class ,eviction = MyBatisRedisCache.class)
public interface UserMapper extends BaseMapper<User>
SpringContextHolder 类
package com.example.mybatisplus.common.ioc;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;
@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, DisposableBean
private static ApplicationContext applicationContext = null;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
SpringContextHolder.applicationContext = applicationContext;
public static ApplicationContext getApplicationContext()
assertContextInjected();
return applicationContext;
public static <T> T getBean(String name)
assertContextInjected();
return (T) applicationContext.getBean(name);
public static <T> T getBean(Class<T> requiredType)
assertContextInjected();
return applicationContext.getBean(requiredType);
public static void clearHolder()
applicationContext = null;
@Override
public void destroy() throws Exception
SpringContextHolder.clearHolder();
private static void assertContextInjected()
Assert.state(applicationContext != null,"applicaitonContext属性未注入");
测试,缓存里没数据,读取数据库
缓存有数据,不读取数据库
本博客代码例子可以在GitHub找到下载链接
以上是关于SpringBoot系列之使用Redis做Mybatis二级缓存的主要内容,如果未能解决你的问题,请参考以下文章
重学springboot系列之集群多节点应用session共享,redis分布式锁
Spring Boot之集成Redis:Spring Cache + Redis
Java之Spring Boot入门到精通IDEA版SpringBoot整合其他框架Junit,Redis,MyBatis(一篇文章精通系列)中