spring-boot使用redis开启mybatis二级缓存

spring-boot使用redis开启mybatis二级缓存

缓存是在查询数据库时,先查询缓存中是否存在查询结果,如果存在,直接从缓存中拿,如果不存在,查询数据库,并将查询结果写入缓存。

一、spring-boot自定义二级缓存

1、redis引入依赖


        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-starter-data-redisartifactId>
        dependency>
        <dependency>
            <groupId>redis.clientsgroupId>
            <artifactId>jedisartifactId>
            <version>3.2.0version>
        dependency>

2、redis链接参数

spring:
  datasource:
	  redis:
	    host: centos
	    port: 6379
	    timeout: 5s
	    lettuce:
	      shutdown-timeout: 100ms
	      pool:
	        max-active: 10
	        max-idle: 8
	        max-wait: 5ms
	        min-idle: 1

3、实现Cache类自定义二级缓存

package com.baizhi.cache;

import com.baizhi.ApplicationContextHolder;
import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;

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

public class UserDefineRedisCache implements Cache {
	//日志
    private static final Logger logger = LoggerFactory.getLogger(UserDefineRedisCache.class);
    private String id;//namespace
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();//读写锁
    //调用工具类ApplicationContextHolder(下面定义)从spring工厂拿redisTemplate类,用于链接redis
    private RedisTemplate redisTemplate =(RedisTemplate)ApplicationContextHolder.getBean("redisTemplate");
	/**
	* mybatis自动调用,id为namespace
	*/
    public UserDefineRedisCache(String id) {
        this.id = id;
    }
	/**
	* mybatis自动调用,id为namespace
	*/
    @Override
    public String getId() {
        return this.id;
    }
	/**
	* mybatis自动调用,o为时间戳+sql+类信息 o1为查询结果
	* 将查询结果存入redis缓存
	*/
    @Override
    public void putObject(Object o, Object o1) {
        logger.debug("将查询结果缓存到Redis");
        ValueOperations valueOperations = redisTemplate.opsForValue();
        valueOperations.set(o, o1, 30, TimeUnit.SECONDS);
    }
	/**
	* mybatis自动调用,o为时间戳+sql+类信息
	* 从redis缓存获取查询结果
	*/
    @Override
    public Object getObject(Object o) {
        logger.debug("获取缓存结果");
        ValueOperations valueOperations = redisTemplate.opsForValue();
        return valueOperations.get(o);
    }
	/**
	* mybatis自动调用,o为时间戳+sql+类信息
	* 删除对应key的缓存
	*/
    @Override
    public Object removeObject(Object o) {
        logger.debug("删除Redis中的Key:" + o);
        ValueOperations valueOperations = redisTemplate.opsForValue();
        Object value = valueOperations.get(o);
        redisTemplate.delete(o);
        return value;
    }
	/**
	* mybatis自动调用
	* 删除所有缓存
	*/
    @Override
    public void clear() {
        logger.debug("删除所有Redis中的缓存");
        redisTemplate.execute((RedisCallback) connection -> {
            connection.flushDb();
            return null;
        });
    }
	/**
	* 缓存项个数
	*/
    @Override
    public int getSize() {
        return 0;
    }
	/**
	* 获取读写锁
	*/
    @Override
    public ReadWriteLock getReadWriteLock() {
        return readWriteLock;
    }
}

4、定义工具类从工厂获取类对象

因为mybatis不能从工厂中自动注入类,所有使用工具类ApplicationContextHolder为上个类UserDefineRedisCache自动注入RedisTemplate

package com.baizhi;

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

@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext applicationContext = null;
	/**
	* spring自动调用,获取ApplicationContext工厂容器
	*/
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }
	/**
	* 使用类名从工厂获取类对象
	*/
    public static Object getBean(String beanName) {
        return applicationContext.getBean(beanName);
    }
   /**
	* 使用类型从工厂获取类对象
	*/
    public static Object getBean(Class clazz) {
        return applicationContext.getBean(clazz);
    }
}

5、将RedisTemplate交给工厂管理

package com.baizhi;

import org.mybatis.spring.annotation.MapperScan;
import org.mybatis.spring.annotation.MapperScans;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.web.client.RestTemplate;

@SpringBootApplication
@MapperScans(value = {@MapperScan(basePackages = "com.baizhi.dao")})
public class UserModelApplication {
    /**
     * spring-boot入口方法
     * @param args
     */
    public static void main(String[] args) {
        SpringApplication.run(UserModelApplication.class, args);
    }
    /**
     * 将RedisTemplate交给工厂,链接redis
     * @param redisConnectionFactory
     * @return
     */
    @Bean
    public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
        RedisTemplate redisTemplate=new RedisTemplate();
        redisTemplate.setConnectionFactory(redisConnectionFactory);
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }
}

你可能感兴趣的:(redis,mybatis,mybatis,redis,缓存,spring)