如何在原生Java(非Spring Boot)中用Jedis从Redis组合键查询数据?
原生Java(Jedis)实现Redis组合键缓存方案
核心思路
Spring Boot的@Cacheable本质是自动帮你生成规范的缓存键(比如items::1这类格式),并封装了"查缓存→缓存命中直接返回→未命中查DB→写入缓存"的逻辑。用原生Java+Jedis的话,这些步骤都需要你手动实现,核心就是自己拼接组合键,再手动完成缓存读写逻辑。
具体实现代码
1. 组合键生成工具方法
用固定分隔符(比如::)把缓存名和多个参数拼接成唯一键,避免不同业务的键冲突:
private String generateCompositeKey(String cacheName, Object... keyParts) { StringBuilder keyBuilder = new StringBuilder(cacheName); for (Object part : keyParts) { keyBuilder.append("::").append(part); } return keyBuilder.toString(); }
2. 模拟@Cacheable的缓存查询方法
假设你要通过id和categoryId两个参数查询数据,完整实现如下:
// 假设已初始化好Jedis连接(实际项目建议用连接池) private Jedis jedis = new Jedis("localhost", 6379); private ItemRepository itemRepository; // 你的数据库操作类 public Item getItem(Integer id, String categoryId) { // 生成组合缓存键 String cacheKey = generateCompositeKey("items", id, categoryId); // 第一步:查询Redis缓存 String cachedItemJson = jedis.get(cacheKey); if (cachedItemJson != null) { // 将JSON字符串反序列化为Item对象(这里用Jackson示例) ObjectMapper objectMapper = new ObjectMapper(); try { return objectMapper.readValue(cachedItemJson, Item.class); } catch (JsonProcessingException e) { e.printStackTrace(); // 反序列化失败则降级查DB } } // 第二步:缓存未命中,查询数据库 Item item = itemRepository.findByIdAndCategoryId(id, categoryId) .orElseThrow(RuntimeException::new); System.out.println("Loading data from DB " + item); // 第三步:将DB查询结果写入Redis缓存,设置过期时间(可选,防止缓存脏数据) try { ObjectMapper objectMapper = new ObjectMapper(); String itemJson = objectMapper.writeValueAsString(item); jedis.setex(cacheKey, 3600, itemJson); // 缓存1小时 } catch (JsonProcessingException e) { e.printStackTrace(); } return item; }
关键注意事项
- 键的唯一性:组合键的拼接规则要固定,确保相同参数生成的键完全一致,不同参数生成的键绝不重复
- 序列化处理:Redis只能存储字符串,所以必须把Java对象序列化为JSON或其他格式(Jackson、Gson都是常用选择)
- 缓存过期策略:建议给缓存设置合理的过期时间,避免数据库数据更新后,缓存长时间不一致
- 异常降级:遇到Redis连接失败、序列化异常时,要直接走数据库查询,不能影响正常业务
内容的提问来源于stack exchange,提问作者user13906258
相关产品推荐
相关产品推荐

