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

所属分类: 软件编程 / java 阅读数: 30
收藏 0 赞 0 分享

建议缓存放到 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作为二级缓存的方法,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对脚本之家网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

更多精彩内容其他人还在看

Springmvc restful配置遇到的小坑

本文是小编给大家带了的Springmvc restful配置遇到的小小坑,小编给大家带来了问题原因及解决办法,非常不错,具有参考借鉴价值,感兴趣的朋友一起看下吧
收藏 0 赞 0 分享

Java中的匿名内部类小结

java内部类分为: 成员内部类、静态嵌套类、方法内部类、匿名内部类。这篇文章主要介绍了Java中的匿名内部类的相关资料,需要的朋友可以参考下
收藏 0 赞 0 分享

Java的云打印Lodop

这篇文章主要介绍了Java的云打印Lodop 的相关资料,非常不错,具有参考借鉴价值,需要的朋友可以参考下
收藏 0 赞 0 分享

Java线程池框架核心代码解析

这篇文章主要针对Java线程池框架核心代码进行详细解析,分析Java线程池框架的实现ThreadPoolExecutor,感兴趣的小伙伴们可以参考一下
收藏 0 赞 0 分享

Java 交换两个变量的数值实现方法

下面小编就为大家带来一篇Java 交换两个变量的数值实现方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

全面了解JAVA_BaseDAO数据处理类

下面小编就为大家带来一篇全面了解JAVA_BaseDAO数据处理类。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

java、python、JavaScript以及jquery循环语句的区别

本篇文章主要介绍java、python、JavaScript以及jquery的循环语句的区别,这里整理了它们循环语句语法跟示例,以便大家阅读,更好的区分它们的不同
收藏 0 赞 0 分享

基于JDBC封装的BaseDao(实例代码)

下面小编就为大家带来一篇基于JDBC封装的BaseDao(实例代码)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

简单通用JDBC辅助类封装(实例)

下面小编就为大家带来一篇简单通用JDBC辅助类封装(实例)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享

浅谈java线程中生产者与消费者的问题

下面小编就为大家带来一篇浅谈java线程中生产者与消费者的问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
收藏 0 赞 0 分享
查看更多