SpringBoot配置Redis对Mybatis的二级缓存进行缓存

Mybatis缓存分一级,二级
一级:sqlSession缓存,和数据库的一个会话,会话完成就关闭了。
二级:mapper缓存,整个服务期间都存在,所以redis对二级进行缓存。

开始配置二级缓存

  1. 在Mybatis配置文件中开启二级缓存
    SpringBoot配置Redis对Mybatis的二级缓存进行缓存_第1张图片
  2. 在XxxMapper.xml中开启当前mapper的namespace的二级缓存,可以在此处使用开启mapper二级缓存,也可以使用@CacheNamespace注解在关联的XxxMapper接口文件上启动二级缓存,两者只能选其一



    
    
……

@Mapper
@CacheNamespace(eviction = MybatisRedisCache.class,implementation = MybatisRedisCache.class)
public interface SysPermMapper extends BaseMapper {

    List getUser();
}
  1. 新建MybatisRedisCache,实现Cache接口并重写全部的抽象方法
package com.cy.crm.util;

import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisServerCommands;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Set;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * @ClassName MybatisRedisCache
 * @Description Redis对Mybatis的缓存
 * @Author Jack.Hu
 */
public class MybatisRedisCache implements Cache {

    private static Logger log = LoggerFactory.getLogger(MybatisRedisCache.class);
	// 读写锁
    private final ReadWriteLock lock = new ReentrantReadWriteLock(true);

    // 这里使用redis缓存,使用springBoot自动注入
    @Autowired
    private RedisTemplate redisTemplate;

    private String id;

    public MybatisRedisCache(final String id){
        if(null == id){
            throw new IllegalStateException("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) SpringContextHolder.getApplicationContext().getBean("redisJsonTemplate");
        }
        if(value != null){
            redisTemplate.opsForValue().set(key.toString(),value);
        }
    }

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

    @Override
    public Object getObject(Object key) {
        try{
            if(null != key){
                return redisTemplate.opsForValue().get(key.toString());
            }
        }catch(Exception e){
            log.error("缓存错误");
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        if(null != key){
            return redisTemplate.delete(key.toString());
        }
        return null;
    }

    @Override
    public void clear() {
        log.debug("情空缓存");
        if(null == redisTemplate){
            redisTemplate = (RedisTemplate) SpringContextHolder.getApplicationContext().getBean("redisJsonTemplate");
        }
        Set keys = redisTemplate.keys("*:" + this.id + "*");
        for (String key : keys) {
            redisTemplate.delete(key);
        }
    }

    /**
     * 获取缓存中的缓存数量
     * @return
     */
    @Override
    public int getSize() { // 获取缓存中的缓存数量
        return  redisTemplate.execute((RedisCallback) RedisServerCommands::dbSize).intValue();
    }


}

注意:由于RedisTemplate的注入可能在应用启动期间没有成功进行注入到缓存内中,需要在使用缓存时中进行手动注入,这是需要从应用的上下文获取RedisTemplate,需要定义一个获取应用上下文的类实现ApplicationContextAware接口,通过这个类来获取应用上下文,通过应用上下文来获取注册到应用上下文的bean!

package com.cy.crm.util;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @ClassName SpringContextHolder 
 * @Description TODO
 * @Author Jack Hu
 */
@Component
public class SpringContextHolder implements ApplicationContextAware {

    private static ApplicationContext applicationContext;

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

    public static ApplicationContext getApplicationContext(){
        assertApplicationContext();
        return applicationContext;
    }

    public static T getBean(String beanName){
        assertApplicationContext();
        return (T)applicationContext.getBean(beanName);
    }

    public static T getBean(Class requiredType){
        assertApplicationContext();
        return applicationContext.getBean(requiredType);
    }

    private static void assertApplicationContext(){
        if(null == SpringContextHolder.applicationContext){
            throw new RuntimeException("applicationContext属性为null,请检查是否注入成功!");
        }
    }

}

你可能感兴趣的:(Redis缓存)