新闻详情

新闻详情

首页 / 资讯中心 / 详情

Spring Cache 如何缓存空结果,避免反复查数据库?

发布时间:2026/9/16 7:55:10来源:尧图网络
Spring Cache 如何缓存空结果,避免反复查数据库?
Spring Cache 如何缓存空结果避免反复查数据库开篇用户不存在查询结果是 null。若每次都把它当成“缓存没命中”相同请求还是会反复查数据库。要缓存空结果先得分清没查过还是查过但没有。环境JDK 21、Spring Framework 6、Spring Boot 3。示例使用应用自有的 RedisCache 适配器不是 Spring Data Redis 的同名类本地往返验证使用隔离 Redis 3不代表生产版本选型。坑点坑点一只看结果是不是 null丢掉了命中状态Spring Cache 的返回需要分清命中状态cache.get(key) 的结果含义返回 null没命中返回 ValueWrapper里面是 null命中了空结果返回 ValueWrapper里面有值命中了普通结果如果拿到包装器后只判断里面的值就会把第二种情况重新送去查库。正确写法避坑一先看有没有包装器再决定是否加载适配器的加载入口保留了这层区别。命中时直接返回里面的值里面是 null 也不会再执行加载器SuppressWarnings(unchecked)OverridepublicsynchronizedTTget(Objectkey,CallableTvalueLoader){paramNotNull(key,key);ValueWrapperresultthis.get(key);if(result!null){return(T)result.get();}else{TvaluevalueFromLoader(key,valueLoader);this.put(key,value);returnvalue;}}这里的 synchronized 锁住当前缓存对象的这个方法不是分布式锁也不是按 key 加锁。本篇只验证顺序调用时空结果不重复加载不把它当成跨实例并发查询的解决方案。空结果实际存了什么Redis 里不能依靠“没有值”表示“已缓存 null”。写入前继承自 AbstractValueAdaptingCache 的 toStoreValue 会在允许空值时用 NullValue 占位禁止空值时写 null 会抛异常。Overridepublicvoidput(Objectkey,Objectvalue){paramNotNull(key,key);longexpireTimeMillisthis.expireTimeMillis;if(expireTimeMillis0L){this.redisClient.vSet(key.toString(),this.toStoreValue(value));}else{this.redisClient.vSet(key.toString(),this.toStoreValue(value),expireTimeMillis,TimeUnit.MILLISECONDS);}}读取端把占位对象还原成业务上的 nullOverridepublicObjectfromStoreValue(ObjectstoreValue){returnstoreValuenull||storeValueinstanceofNullValue?null:storeValue;}包装器的命中判断发生在这层值还原之外。因此占位对象经过序列化、Redis存储、反序列化后仍须能被识别成 NullValue不能意外变成普通 Map。换序列化器后需要验证这条往返链路。调用示例连续查询两次只加载一次RedisClient 是应用封装需先接好 RedisTemplate、序列化器和 key 配置它不是 JDK 类。下面假定 redisClient 已初始化key 为隔离测试键。AtomicInteger 只用来统计加载次数没有访问真实用户表。RedisCachecachenewRedisCache(users,true,60_000,redisClient);Stringkeyuser:missing;cache.evict(key);AtomicIntegerloadsnewAtomicInteger();CallableObjectloader()-{loads.incrementAndGet();returnnull;};System.out.println(cache.get(key,loader));// nullSystem.out.println(cache.get(key,loader));// nullSystem.out.println(loads.get());// 1Cache.ValueWrapperhitcache.get(key);System.out.println(hit!null);// trueSystem.out.println(hit.get());// nullcache.evict(key);System.out.println(cache.get(key)null);// true参数 true 开启空值缓存60_000 是本适配器配置的过期毫秒数。RedisClient 还可能按配置追加随机过期时间上述验证关闭了这个随机量。有效期内新增用户时需要删除对应空结果否则会暂时继续返回“用户不存在”。正常接入 Spring 缓存注解还需要注册 CacheManager、命名缓存并开启缓存支持。仅有这个类不会让 Cacheable 自动生效如果注解用 unless 排除了 null空结果也不会进入缓存。删除与有效期要一并确认这份适配器的单键删除会调用 RedisClient但 clear 没有清理逻辑Overridepublicvoidevict(Objectkey){paramNotNull(key,key);this.redisClient.kDelete(key.toString());}Overridepublicvoidclear(){}因此不能把 CacheEvict(allEntries true) 当作已经实现的批量清除方案。此处的 key 直接传给客户端不会自动加上 cacheName不同业务应使用不会冲突的 key 命名。总结缓存空结果关键是保留“是否命中”和“结果是什么”这两层信息。开启空值存储、验证占位对象往返再配合有效期和单键失效才能减少同一空结果的重复查询随机 key、并发首次加载和批量清理仍需分别处理。如果这篇文章对您有用欢迎关注。后续会继续拆解 Java 后端的实用代码讲清写法、原理和使用时要注意的细节。
网站建设高端定制企业官网
RELATED

相关资讯

更多精彩内容,欢迎继续阅读

较早相关资讯

最新相关资讯

PLC工程能力生成地图:从语法学习到产线实战的五阶跃迁 2026/9/16 8:28:34

PLC工程能力生成地图:从语法学习到产线实战的五阶跃迁

1. 这不是培训失效,是能力转化断层的真实写照“为什么PLC编程培训班学完还是不会干活?”——这句话在自动化工程师群、工厂技术主管茶水间、甚至招聘HR的面试复盘会上,已经不是吐槽,而是共识性诊断。我带过27期西门子S7-1200实操班…

阅读更多 →
ESP32蓝牙Beacon测距实战:从RSSI波动到1米精度 2026/9/16 8:28:34

ESP32蓝牙Beacon测距实战:从RSSI波动到1米精度

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

阅读更多 →
AWS CLI 深入解析:使用 `codebuild batch-get-projects` 批量查询 CodeBuild 构建项目详情 2026/9/16 8:28:34

AWS CLI 深入解析:使用 `codebuild batch-get-projects` 批量查询 CodeBuild 构建项目详情

AWS CLI 深入解析:使用 codebuild batch-get-projects 批量查询 CodeBuild 构建项目详情 【免费下载链接】aws-cli Universal Command Line Interface for Amazon Web Services 项目地址: https://gitcode.com/GitHub_Trending/aw/aws-cli aws codebuild bat…

阅读更多 →
【Rust入门知识点学与练】第36课:所有权——移动、借用、Copy、切片 2026/9/16 8:28:34

【Rust入门知识点学与练】第36课:所有权——移动、借用、Copy、切片

本课目标: 不再靠「试出来的」.clone() 过编译。学完你应该能看着一个签名说出「这个函数会拿走我的东西」,并在写代码前先决定好谁拥有谁。 本课是 Rust 的分水岭。前面是语法,从这里开始才是 Rust。建议一次只读一半,中间一定要…

阅读更多 →
aws cloudwatch disable-insight-rules 详解:批量停用 Contributor Insights 规则 2026/9/16 8:28:34

aws cloudwatch disable-insight-rules 详解:批量停用 Contributor Insights 规则

aws cloudwatch disable-insight-rules 详解:批量停用 Contributor Insights 规则 【免费下载链接】aws-cli Universal Command Line Interface for Amazon Web Services 项目地址: https://gitcode.com/GitHub_Trending/aw/aws-cli 导读 本文围绕 AWS CLI …

阅读更多 →
基于RAG的PHP微信AI客服系统:源码实践与部署解析 2026/9/16 8:25:30

基于RAG的PHP微信AI客服系统:源码实践与部署解析

最近把一套PHP原创微信AI客服系统的源码完整梳理了一遍,顺手用在了几个客户的项目里,效果超出预期。微信生态里做客服系统并不新鲜,但把AI能力尤其是大模型语义理解融入其中,让机器人真正能扛住全天候的咨询压力,这条路…

阅读更多 →

今日资讯

本周资讯

本月资讯

看完文章仍有疑问?

联系尧图顾问,获取一对一建站咨询

立即免费咨询 📞 400-888-8888
📞