Springboot+Mybatis+Redis实现二级缓存

Springboot+Mybatis+Redis实现二级缓存

环境准备

  • 引依赖
<!--集成Redis二级缓存-->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-pool2</artifactId>
</dependency>
  • 配置application.yaml
#服务基本配置
server:
  port: 8888
  servlet:
    context-path: /
#数据源
spring:
  datasource:
    type: com.alibaba.druid.pool.DruidDataSource
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://10.15.0.13:3306/project
    username: root
    password: root
 #配置redis
  redis:
    host: hbase
    port: 6379
    timeout: 5s
    lettuce:
      shutdown-timeout: 100s
      pool:
        max-active: 10
        max-idle: 8
        max-wait: 5ms
        min-idle: 1
#配置mapper
mybatis:
  mapper-locations: classpath:com/baizhi/mapper/*Mapper.xml
  type-aliases-package: com.baizhi.entity
  #开启Mybatis的批处理模式
  executor-type: batch
  #开启Mybatis的二级缓存
  configuration:
    cache-enabled: true
  • 在入口类自定义redisConnectionFactory
@SpringBootApplication
@MapperScan(basePackages = "com.baizhi.dao")
public class UserModelApplication {
    public static void main(String[] args) {
        SpringApplication.run(UserModelApplication.class,args);
    }

    //SpringMVC中自带一个Rest客户端工具 可以无缝和SpringBoot集成
    @Bean
    public RestTemplate restTemplate(){
        return new RestTemplate();
    }

    @Bean
    //会从上下文中自动注入redisConnectionFactory
    public RedisTemplate<Object, Object> redisTemplate(LettuceConnectionFactory connectionFactory) throws UnknownHostException {
        RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(connectionFactory);
        //设置key,value的序列化   默认序列化是Jdk
        redisTemplate.setKeySerializer(new JdkSerializationRedisSerializer());
        //将序列化的对象转成json的序列化
        redisTemplate.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return redisTemplate;
    }
}
  • 在userDaoMapper.xml里开启缓存
<mapper namespace="com.baizhi.dao.UserDAO">
    <cache type="com.baizhi.cache.UserDefineRedisCache">
        <property name="timeout" value="60"/>
    </cache>
  • 实现Cache接口
//此类没有交给String工厂 需要实现ApplicationContextAware并配置 才可以获得redisTemplate
public class UserDefineRedisCache implements Cache {
    private Logger log= LoggerFactory.getLogger(UserDefineRedisCache.class);
    private String namespace; //存储namespace

    private RedisTemplate redisTemplate=(RedisTemplate) ApplicationContextHolder.getBean("redisTemplate");

    private long timeout=300;
    //涉及并发操作缓存需要加锁
    private ReadWriteLock readWriteLock=new ReentrantReadWriteLock(); //读写锁

    //将Dao的namespace传进来
    public UserDefineRedisCache(String namespace){
        this.namespace=namespace;
    }
    @Override
    public String getId() {
        return namespace;
    }

    @Override
    //查询结果存储到缓存区
    public void putObject(Object key, Object value) {
        log.debug("将查询结果存储到cache.key:"+key+",value"+value);
        ValueOperations operations = redisTemplate.opsForValue();
        operations.set(key,value,timeout, TimeUnit.SECONDS);
    }

    @Override
    //读取缓存中的结果
    public Object getObject(Object key) {
        log.debug("从缓存中读取结果.key:"+key);
        ValueOperations operations = redisTemplate.opsForValue();
        return operations.get(key);
    }

    @Override
    //清除缓存
    public Object removeObject(Object key) {
        log.debug("从缓存中清除.key:"+key);
        ValueOperations operations = redisTemplate.opsForValue();
        Object value = operations.get(key);
        redisTemplate.delete(key);
        return value;
    }

    @Override
    //清除缓存区所有数据
    public void clear() {
        log.debug("从缓存区删除所有数据");
        redisTemplate.execute(new RedisCallback() {
            @Override
            public Object doInRedis(RedisConnection connection) throws DataAccessException {
                connection.flushAll();
                return null;
            }
        });
    }

    @Override
    public int getSize() {
        return 0;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        //将读写锁返回
        return readWriteLock;
    }

    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }
}
  • 调用timeplate工厂(需要实现ApplicationContextAware)
@Component
public class ApplicationContextHolder implements ApplicationContextAware {
    private static ApplicationContext applicationContext;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public static Object getBean(String beanName){
        return applicationContext.getBean(beanName);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值