前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >SpringBoot系列之使用Redis做Mybatis二级缓存

SpringBoot系列之使用Redis做Mybatis二级缓存

作者头像
SmileNicky
发布2022-01-04 16:51:32
6070
发布2022-01-04 16:51:32
举报
文章被收录于专栏:Nicky's blog

开发环境

  • JDK 1.8
  • SpringBoot2.2.1
  • MybatisPlus3.4.3.4
  • Maven 3.2+
  • Mysql5.7.36
  • 开发工具
    • IntelliJ IDEA
    • smartGit

选择mybatis plus framework

然后项目基础架构搭建好之后,加上redis配置

代码语言:javascript
复制
<dependency>
   <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

加上redis配置:

代码语言:javascript
复制
spring:
  redis:
    host: 127.0.0.1
    port: 6379
    password:
    database: 0

MyBatisPlus开启缓存支持

实现Cache接口,因为这个类不是Spring管理的,所以通过SpringContextHolder从ioc容器里获取redisTemplate类

代码语言:javascript
复制
package com.example.mybatisplus.common.cache;


import com.example.mybatisplus.common.ioc.SpringContextHolder;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.util.StringUtils;

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

@Slf4j
public class MyBatisRedisCache implements Cache {

    private static RedisTemplate<String , Object> redisTemplate;

    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);

    private String id;


    public MyBatisRedisCache(String id) {
        if (StringUtils.isEmpty(id)) {
            throw new IllegalArgumentException("cache instances require an id.");
        }
        this.id = id;
        if (redisTemplate == null) {
            redisTemplate = SpringContextHolder.getBean("redisTemplate");
        }
    }

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

    @Override
    public void putObject(Object key, Object value) {
        if (!StringUtils.isEmpty(value)) {
            redisTemplate.opsForHash().put(id, key.toString() , value);
            log.info("mybatis缓存,{}:[{}]" , key , value );
        }
    }

    @Override
    public Object getObject(Object key) {
        if (!StringUtils.isEmpty(key)) {
            Object object = redisTemplate.opsForHash().get(id , key.toString());
            log.info("mybatis缓存读取,{}:[{}]", key , object);
            return object;
        }
        return null;
    }

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

    @Override
    public void clear() {
        redisTemplate.delete(id.toString());
    }

    @Override
    public int getSize() {
        return redisTemplate.opsForHash().size(id.toString()).intValue();
    }

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


}

修改CacheNamespace指定缓存类,implementation 属性:默认是PerpetualCache类,即hashMap实现

代码语言:javascript
复制
package com.example.mybatisplus.mapper;

import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mybatisplus.common.cache.MyBatisRedisCache;
import com.example.mybatisplus.model.User;
import org.apache.ibatis.annotations.CacheNamespace;

@DS(value = "shop")
@CacheNamespace(implementation = MyBatisRedisCache.class ,eviction = MyBatisRedisCache.class)
public interface UserMapper extends BaseMapper<User>{

}

SpringContextHolder 类

代码语言:javascript
复制
package com.example.mybatisplus.common.ioc;


import org.springframework.beans.BeansException;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

@Service
@Lazy(false)
public class SpringContextHolder implements ApplicationContextAware, DisposableBean {

    private static ApplicationContext applicationContext = null;

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

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

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

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

    public static void clearHolder() {
        applicationContext = null;
    }

    @Override
    public void destroy() throws Exception {
        SpringContextHolder.clearHolder();
    }

    private static void assertContextInjected() {
        Assert.state(applicationContext != null,"applicaitonContext属性未注入");
    }
}

测试,缓存里没数据,读取数据库

缓存有数据,不读取数据库

本博客代码例子可以在GitHub找到下载链接

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022/01/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
云数据库 Redis®
腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档