引入redis依赖
<!-- redis-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
配置redis
# Redis
spring.redis.host=localhost
spring.redis.port=6379
spring.redis.pool.max-idle=8
spring.redis.pool.min-idle=0
spring.redis.pool.max-active=8
spring.redis.pool.max-wait=-1
spring.redis.database=0
spring.redis.password=xxx
redisTemplate配置
package com.zhy.ysw.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
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.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* redis配置类
*/
@Configuration
public class RedisConfig {
@Bean
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer<Object> jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer<Object>(Object.class);
ObjectMapper om = new ObjectMapper();
om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(om);
// 设置值(value)的序列化采用Jackson2JsonRedisSerializer。
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
// 设置键(key)的序列化采用StringRedisSerializer。
redisTemplate.setKeySerializer(new StringRedisSerializer());
//hash结构的key和value序列化方式
redisTemplate.setHashKeySerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
自定义缓存实现
package com.zhy.ysw.config.cacheConfig;
import com.zhy.ysw.common.commonUtils.SpringUtil;
import org.apache.ibatis.cache.Cache;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.CollectionUtils;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;
/**
* @description: 使用Redis实现Mybatis二级缓存,实现Cache接口 向redis里添加的数据的有效期为2天
* @author: Zhaohy
*
**/
public class MybatisRedisCache implements Cache {
//private static final Logger logger = LoggerFactory.getLogger(MybatisRedisCache.class);
// 读写锁
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
private RedisTemplate<String, Object> redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
private String id;
public MybatisRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
//logger.info("Redis Cache id " + id);
this.id = id;
}
@Override
public String getId() {
return this.id;
}
@Override
public void putObject(Object key, Object value) {
if (value != null) {
// 向Redis中添加数据,有效时间是2天
redisTemplate.opsForValue().set(key.toString(), value, 2, TimeUnit.DAYS);
}
}
@Override
public Object getObject(Object key) {
try {
if (key != null) {
Object obj = redisTemplate.opsForValue().get(key.toString());
return obj;
}
} catch (Exception e) {
//logger.error("redis ");
}
return null;
}
@Override
public Object removeObject(Object key) {
try {
if (key != null) {
redisTemplate.delete(key.toString());
}
} catch (Exception e) {
}
return null;
}
@Override
public void clear() {
//logger.debug("清空缓存");
try {
Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
if (!CollectionUtils.isEmpty(keys)) {
redisTemplate.delete(keys);
}
} catch (Exception e) {
}
}
@Override
public int getSize() {
Long size = (Long) redisTemplate.execute(new RedisCallback<Long>() {
@Override
public Long doInRedis(RedisConnection connection) throws DataAccessException {
return connection.dbSize();
}
});
return size.intValue();
}
@Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
}
用到一个工具类
package com.zhy.ysw.common.commonUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class SpringUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if(SpringUtil.applicationContext == null) {
SpringUtil.applicationContext = applicationContext;
}
System.out.println("========ApplicationContext配置成功,在普通类可以通过调用SpringUtils.getAppContext()获取applicationContext对象,applicationContext="+ SpringUtil.applicationContext+"========");
}
//获取applicationContext
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
//通过name获取 Bean.
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//通过class获取Bean.
public static <T> T getBean(Class<T> clazz){
return getApplicationContext().getBean(clazz);
}
//通过name,以及Clazz返回指定的Bean
public static <T> T getBean(String name,Class<T> clazz){
return getApplicationContext().getBean(name, clazz);
}
}
在配置文件内加入如下配置
#开启mybatis二级缓存
mybatis:
configuration:
cache-enabled: true
在每一个mapper接口类上面加入上如下注解
//开启mybatis二级缓存,加载自定义缓存配置
@CacheNamespace(implementation = com.zhy.ysw.config.cacheConfig.MybatisRedisCache.class)