浅析SpringBoot整合Mybatis如何实现二级缓存

 更新时间:2025年05月15日 10:35:10   作者:哪里的破水瓶  
二级缓存,是指多个Sqlsession之间共享数据,但是也可以使用Redis这样的缓存作为存储点,但是不支持mybatisplus 里的方法,本文我们就来聊聊SpringBoot整合Mybatis实现二级缓存的相关方法吧

mybatis 原生

二级缓存,是指多个Sqlsession之间共享数据,但是也可以使用Redis这样的缓存作为存储点。 但是不支持mybatisplus 里的方法。

处理类,用于拦截mapper缓存。

import org.apache.ibatis.cache.Cache;
public record MybatisRedisCache(String id) implements Cache {

    private static final StringRedisTemplate redisTemplate;

    static {
        redisTemplate = SpringUtil.getBean(StringRedisTemplate.class);
    }

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

    @Override
    public void putObject(Object key, Object value) {
        if (value != null) {
            redisTemplate.opsForValue().set(getKey(key), JSONUtil.toJsonStr(value));
        }
    }

    @Override
    public Object getObject(Object key) {
        String string = redisTemplate.opsForValue().get(getKey(key));
        if (string == null) return null;
        return isArray(string);
    }

    @Override
    public Object removeObject(Object key) {
        String redisKey = getKey(key);
        Object value = redisTemplate.opsForValue().get(redisKey);
        redisTemplate.delete(redisKey);
        return value;
    }

    @Override
    public void clear() {
        redisTemplate.delete(Objects.requireNonNull(redisTemplate.keys(getKey("*"))));
    }

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

    private String getKey(Object key) {
        return id + ":" + key.hashCode();
    }

    public Object isArray(String str) {
        JSON json = JSONUtil.parse(str);
        if (json instanceof cn.hutool.json.JSONArray) {
            // 是数组
            return JSONUtil.toList((cn.hutool.json.JSONArray) json, Object.class);
        }
        if (json instanceof cn.hutool.json.JSONObject) {
            // 是对象
            return JSONUtil.toBean((cn.hutool.json.JSONObject) json, Object.class);
        }
        throw new RuntimeException("缓存数据格式错误");
    }

}

mapper xml

一定要加 cache-ref 才能进行二级缓存

<mapper namespace="com.example.dao.UserMapper">

    <cache-ref namespace="com.example.dao.UserMapper"/>

    <select id="selectAll" resultType="com.example.Demo">
        select *
        from demo
    </select>
</mapper>

配置 CacheNamespace 使用就可以了

@CacheNamespace(implementation = MybatisRedisCache.class)
public interface UserMapper extends BaseMapper<Demo> {

    List<Demo> selectAll();

}

Spring Cache

@Configuration
@EnableCaching
public class RedisCacheConfig {

    @Bean
    public CacheManager cacheManager(RedisConnectionFactory factory) {
        RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
                .entryTtl(Duration.ofMinutes(10)) // 默认缓存 10 分钟
                .disableCachingNullValues() // 避免存入控制
                .serializeValuesWith( // 设置序列化
                        RedisSerializationContext.SerializationPair.fromSerializer(new GenericJackson2JsonRedisSerializer())
                );
        // 返回
        return RedisCacheManager.builder(factory).cacheDefaults(config).build();
    }

}

Cacheable 缓存、CacheEvict 删除,拼接 key

@Service
public class DemoService extends ServiceImpl<UserMapper, Demo> {

    @Cacheable(value = "user:cache", key = "#id")
    public Demo getOne(Long id) {
        return getById(id);
    }


    @Caching(evict = {
            @CacheEvict(value = "user:cache", key = "#id"),
            @CacheEvict(value = "user:all", allEntries = true)}
    )
    public void deleteById(String id) {
        removeById(id);
    }

    // 更新数据后刷新缓存
    @Caching(
            put = {@CachePut(value = "user:cache", key = "#demo.id", unless = "#result == null")},
            evict = {@CacheEvict(value = "user:all", allEntries = true)}
    )
    public void updateUser(Demo demo) {
        updateById(demo);
    }

    @Cacheable(value = "user:all")
    public List<Demo> listDemo() {
        return list();
    }

}

到此这篇关于浅析SpringBoot整合Mybatis如何实现二级缓存的文章就介绍到这了,更多相关SpringBoot Mybatis二级缓存内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java使用BigDecimal进行运算封装的实际案例

    Java使用BigDecimal进行运算封装的实际案例

    今天小编就为大家分享一篇关于Java使用BigDecimal进行运算封装的实际案例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2018-12-12
  • Spring boot 集成 MQTT详情

    Spring boot 集成 MQTT详情

    这篇文章主要介绍了Spring boot 集成 MQTT详情,MQTT是一种基于发布/订阅模式的"轻量级"通讯协议,可以以极少的代码和有限的带宽为连接远程设备提供实时可靠的消息服,下文更多相关介绍,需要的小伙伴可以参考一下
    2022-04-04
  • springboot 使用 minio的示例代码

    springboot 使用 minio的示例代码

    Minio是Apcche旗下的一款开源的轻量级文件服务器,基于对象存储,协议是基于Apache License v2.0,开源可用于商务,本文给大家介绍下springboot 使用 minio的示例代码,感兴趣的朋友看看吧
    2022-03-03
  • Spring Boot实现分布式任务调度的步骤

    Spring Boot实现分布式任务调度的步骤

    Spring Boot提供了一些工具和框架,可以帮助我们轻松地实现分布式任务调度,在本文中我们将介绍如何使用Spring Boot、Spring Cloud、Quartz和Redis来实现分布式任务调度,感兴趣的朋友跟随小编一起看看吧
    2023-06-06
  • idea使用pagehelper实现后端分页功能的步骤详解

    idea使用pagehelper实现后端分页功能的步骤详解

    这篇文章主要介绍了idea使用pagehelper实现后端分页功能的步骤,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-09-09
  • 详解SpringCloud-Alibaba-Seata分布式事务

    详解SpringCloud-Alibaba-Seata分布式事务

    这篇文章主要介绍了SpringCloud-Alibaba-Seata分布式事务的相关知识,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-12-12
  • Spring Boot如何优雅的使用多线程实例详解

    Spring Boot如何优雅的使用多线程实例详解

    这篇文章主要给大家介绍了关于Spring Boot如何优雅的使用多线程的相关资料,文中通过示例代码介绍的非常详细,对大家学习或者使用Spring Boot具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧
    2020-05-05
  • SpringBoot整合Shiro的方法详解

    SpringBoot整合Shiro的方法详解

    Apache Shiro是一个java安全(权限)框架,Shiro可以非常容易的开发出足够好的应用,其不仅可以用在javase环境,也可以用在javaee环境。本文介绍了SpringBoot整合Shiro的方法,需要的可以参考一下
    2022-05-05
  • 提升性能秘密武器Java Unsafe类面试精讲

    提升性能秘密武器Java Unsafe类面试精讲

    这篇文章主要为大家介绍了提升性能秘密武器Java Unsafe类面试精讲,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-10-10
  • java自带排序使用

    java自带排序使用

    这篇文章主要给大家分享了java自带排序使用,该方法是升序排序,方法的内部采用了快排实现,但该方法是 稳定的。下面一起来看看文章的详细介绍吧
    2021-12-12

最新评论