您的位置:首页 > 数据库 > Redis

mybatis plus使用redis作为二级缓存的方法

2019-10-29 07:07 1386 查看

建议缓存放到 service 层,你可以自定义自己的 BaseServiceImpl 重写注解父类方法,继承自己的实现。为了方便,这里我们将缓存放到mapper层。mybatis-plus整合redis作为二级缓存与mybatis整合redis略有不同。

1. mybatis-plus开启二级缓存

mybatis-plus.configuration.cache-enabled=true

2. 定义RedisTemplate的bean交给spring管理,这里为了能将对象直接存取到redis中,进行了一些序列化的操作

@Bean(value = "redisTemplate")
public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(connectionFactory);
//Use Jackson 2Json RedisSerializer to serialize and deserialize the value of redis (default JDK serialization)
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
//将类名称序列化到json串中
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
//设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);

//Use String RedisSerializer to serialize and deserialize the key value of redis
RedisSerializer redisSerializer = new StringRedisSerializer();
//key
redisTemplate.setKeySerializer(redisSerializer);
redisTemplate.setHashKeySerializer(redisSerializer);
//value
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);

redisTemplate.afterPropertiesSet();
return redisTemplate;

}

3. 自定义自己的缓存管理

package com.qctchina.headsetserver.config;

import com.qctchina.headsetserver.util.SpringUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.connection.RedisServerCommands;
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.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
* @author shuangyueliao
* @create 2019/9/10 14:02
* @Version 0.1
*/
@Slf4j
public class MybatisRedisCache implements Cache {

// 读写锁
private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

//这里使用了redis缓存,使用springboot自动注入
private RedisTemplate<String, Object> redisTemplate;

private String id;

public MybatisRedisCache(final String id) {
if (id == null) {
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
}

@Override
public String getId() {
return this.id;
}

@Override
public void putObject(Object key, Object value) {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
if (value != null) {
redisTemplate.opsForValue().set(key.toString(), value);
}
}

@Override
public Object getObject(Object key) {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
try {
if (key != null) {
return redisTemplate.opsForValue().get(key.toString());
}
} catch (Exception e) {
e.printStackTrace();
log.error("缓存出错 ");
}
return null;
}

@Override
public Object removeObject(Object key) {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
if (key != null) {
redisTemplate.delete(key.toString());
}
return null;
}

@Override
public void clear() {
log.debug("清空缓存");
if (redisTemplate == null) {
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
if (!CollectionUtils.isEmpty(keys)) {
redisTemplate.delete(keys);
}
}

@Override
public int getSize() {
if (redisTemplate == null) {
//由于启动期间注入失败,只能运行期间注入,这段代码可以删除
redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
}
Long size = redisTemplate.execute((RedisCallback<Long>) RedisServerCommands::dbSize);
return size.intValue();
}

@Override
public ReadWriteLock getReadWriteLock() {
return this.readWriteLock;
}
}

SpringUtil是手动获取bean的工具类

@Component
public class SpringUtil implements ApplicationContextAware {

private static ApplicationContext applicationContext;

@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
SpringUtil.applicationContext = applicationContext;
}

public static Object getBean(String name){
return applicationContext.getBean(name);
}

public static <T> T getBean(String name, Class<T> clazz){
return applicationContext.getBean(name, clazz);
}

public static <T> T getBean(Class<T> clazz){
return applicationContext.getBean(clazz);
}
}

4. 在mapper上加上注解@CacheNamespace

@CacheNamespace(implementation= MybatisRedisCache.class,eviction=MybatisRedisCache.class)
public interface CommonMapper extends BaseMapper<Common> {

如果调用该mapper下的方法,那么会使用redis缓存

总结

以上所述是小编给大家介绍的mybatis plus使用redis作为二级缓存的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

您可能感兴趣的文章:

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息