引入依赖
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置application.yml文件
spring:data:redis:host: 127.0.0.1port: 6379database: 8password: roottimeout: 10slettuce:pool:min-idle: 0max-idle: 8max-active: 8max-wait: -1ms
mybatis-plus:global-config:banner: falsetypeAliasesPackage: com.hongri.**.domainmapperLocations: classpath*:mapper/**/*Mapper.xmlconfigLocation: classpath:mybatis/mybatis-config.xml
配置mybatis-config.xml
cacheEnabled
一定要开启,要不然缓存不生效
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><settings><setting name="cacheEnabled" value="true"/><setting name="useGeneratedKeys" value="true"/><setting name="defaultExecutorType" value="SIMPLE"/><setting name="logImpl" value="SLF4J"/></settings></configuration>
redis配置
RedisConfig
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.jsontype.impl.LaissezFaireSubTypeValidator;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.jetbrains.annotations.Contract;
import org.jetbrains.annotations.NotNull;
import org.springframework.cache.annotation.CachingConfigurerSupport;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.data.redis.listener.RedisMessageListenerContainer;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
@EnableCaching
public class RedisConfig extends CachingConfigurerSupport {@Bean(name = "mybaitsCacheTemplate")public RedisTemplate<String, Object> mybaitsTedisTemplate(RedisConnectionFactory connectionFactory) {RedisTemplate<String, Object> template = new RedisTemplate<>();template.setConnectionFactory(connectionFactory);Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<>(Object.class);ObjectMapper objectMapper = new ObjectMapper();objectMapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS);objectMapper.registerModule(new JavaTimeModule());objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);objectMapper.activateDefaultTyping(LaissezFaireSubTypeValidator.instance,ObjectMapper.DefaultTyping.NON_FINAL,JsonTypeInfo.As.WRAPPER_ARRAY);jackson2JsonRedisSerializer.setObjectMapper(objectMapper);StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();template.setKeySerializer(stringRedisSerializer);template.setValueSerializer(jackson2JsonRedisSerializer);template.setHashKeySerializer(stringRedisSerializer);template.setHashValueSerializer(jackson2JsonRedisSerializer);template.afterPropertiesSet();return template;}@Beanpublic DefaultRedisScript<Long> limitScript() {DefaultRedisScript<Long> redisScript = new DefaultRedisScript<>();redisScript.setScriptText(limitScriptText());redisScript.setResultType(Long.class);return redisScript;}@Contract(pure = true)private @NotNull String limitScriptText() {return "local key = KEYS[1]\n" +"local count = tonumber(ARGV[1])\n" +"local time = tonumber(ARGV[2])\n" +"local current = redis.call('get', key);\n" +"if current and tonumber(current) > count then\n" +" return tonumber(current);\n" +"end\n" +"current = redis.call('incr', key)\n" +"if tonumber(current) == 1 then\n" +" redis.call('expire', key, time)\n" +"end\n" +"return tonumber(current);";}}
MyBatisRedisCache
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 = "key前缀:" + id;if (redisTemplate == null) {redisTemplate = SpringUtils.getBean("mybaitsCacheTemplate");}}@Overridepublic String getId() {return this.id;}@Overridepublic void putObject(Object key, Object value) {if (!StringUtils.isEmpty(value)) {redisTemplate.opsForHash().put(id, key.toString() , value);}}@Overridepublic Object getObject(Object key) {if (!StringUtils.isEmpty(key)) {Object object = redisTemplate.opsForHash().get(this.id, key.toString());return object;}return null;}@Overridepublic Object removeObject(Object key) {if (!StringUtils.isEmpty(key)) {redisTemplate.delete(key.toString());}return null;}@Overridepublic void clear() {redisTemplate.delete(id.toString());}@Overridepublic int getSize() {return redisTemplate.opsForHash().size(id.toString()).intValue();}@Overridepublic ReadWriteLock getReadWriteLock() {return readWriteLock;}}
使用缓存
- 在mapper上添加
@CacheNamespace
注解
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.common.core.domain.entity.SysUser;
import com.common.core.redis.MyBatisRedisCache;
import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;
@CacheNamespace(implementation = MyBatisRedisCache.class,eviction = MyBatisRedisCache.class)
public interface SysUserMapper extends BaseMapper<SysUser> {public List<SysUser> selectUserList(SysUser sysUser);
}