引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置application.yml文件
spring:
data:
redis:
host: 127.0.0.1
port: 6379
database: 8
password: root
timeout: 10s
lettuce:
pool:
min-idle: 0
max-idle: 8
max-active: 8
max-wait: -1ms
mybatis-plus:
global-config:
banner: false
typeAliasesPackage: com.hongri.**.domain
mapperLocations: classpath*:mapper/**/*Mapper.xml
configLocation: classpath:mybatis/mybatis-config.xml
配置mybatis-config.xml
cacheEnabled
一定要开启,要不然缓存不生效
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//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;
}
@Bean
public 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");
}
}
@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);
}
}
@Override
public Object getObject(Object key) {
if (!StringUtils.isEmpty(key)) {
Object object = redisTemplate.opsForHash().get(this.id, key.toString());
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;
}
}
使用缓存
- 在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);
}