黑马点评项目shoptype
时间: 2024-02-25 15:45:55 浏览: 245
黑马点评项目中的shoptype是指商铺分类。根据提供的代码,可以看出项目使用了缓存策略来获取shoptype信息。具体来说,有两种缓存策略实现:
1. String缓存策略:首先从Redis中查询商铺缓存,如果存在则直接返回,否则从数据库中查询,并将查询结果存入Redis中。
2. Zset缓存策略:同样首先从Redis中查询商铺缓存,如果存在则直接返回,否则从数据库中查询,并将查询结果按照排序字段存入Redis中。
以上是黑马点评项目中获取shoptype的实现方式,根据具体需求,可以选择使用不同的缓存策略来提高查询效率。
相关问题
黑马点评店铺类型缓存
### 黑马点评店铺类型缓存实现方案
#### 数据库与缓存同步策略
对于黑马点评中的店铺类型的缓存管理,采用的是先更新数据库再删除缓存的方法。当有新的数据变更时,会执行如下操作:
- 首先对数据库内的记录进行修改;
- 修改完成后立即清除对应的缓存条目。
这种方法可以有效防止脏读现象的发生,并确保每次获取的数据都是最新的[^1]。
```java
public Result updateShopType(ShopType shopType) {
Long id = shopType.getId();
if (id == null){
return Result.fail("店铺类型ID不能为空!");
}
// 1. 更新数据库
updateById(shopType);
// 2. 删除缓存
stringRedisTemplate.delete(RedisConstants.CACHE_SHOPTYPE_KEY + id);
return Result.ok();
}
```
#### 处理缓存穿透问题
为了避免缓存穿透带来的性能损耗,在查询特定店铺类型之前增加了额外的验证机制。如果发现请求的目标对象既不在内存也不存在于实际存储介质中,则直接向客户端反馈错误信息而不是将其置入缓存系统内[^2]。
```java
@Override
public Result queryShopTypeById(Long id) {
ShopType shopType = queryWithLogicalExpire(id);
if (shopType == null) {
return Result.fail("该店铺类型不存在");
}
return Result.ok(shopType);
}
```
#### 解决缓存击穿措施
为了应对高并发场景下的热点数据访问压力,引入了带有时间戳标记的有效期控制逻辑。即使某个键已经达到了预设的最大存活期限,只要它仍然处于活跃状态就不会被轻易淘汰掉。这种方式可以在一定程度上缓解因大量瞬时请求造成的服务器资源占用过高问题[^3]。
```java
private ShopType queryWithLogicalExpire(Long id) {
String key = RedisConstants.CACHE_SHOPTYPE_KEY + id;
Object resultObj = redisTemplate.opsForValue().get(key);
if(resultObj != null && !resultObj.toString().equals("")) {
JSONObject jsonObject = JSON.parseObject((String) resultObj);
LocalDateTime expireTime = jsonObject.getDate("expireTime").toInstant()
.atZone(ZoneId.systemDefault())
.toLocalDateTime();
if(expireTime.isAfter(LocalDateTime.now())) {
return JSON.toJavaObject(jsonObject.getJSONObject("data"), ShopType.class);
} else {
// 若已过期则重新加载最新数据至缓存
refreshCache(id, key);
}
}
return null;
}
// 刷新缓存的具体实现...
```
redis黑马点评给店铺类型添加缓存
### 使用 Redis 实现店铺类型数据的缓存
为了实现店铺类型的高效缓存并提升应用性能,可以采用以下策略:
#### 方法设计
定义 `saveShopTypeToRedis` 函数用于保存店铺类型到 Redis 中,并设置合理的逻辑过期时间。此操作不仅能够减少数据库的压力,还能确保即使在高并发场景下也能提供稳定的服务。
```java
public void saveShopTypeToRedis(Long typeId, Long seconds) {
// 查询店铺类型数据
ShopType shopTypeById = getShopTypeById(typeId);
// 封装要存储的数据结构
RedisData redisData = new RedisData();
redisData.setData(shopTypeById);
// 设置逻辑上的过期时间戳
LocalDateTime expireTime = LocalDateTime.now().plusSeconds(seconds);
redisData.setExpireTime(expireTime);
// 序列化对象为JSON字符串形式存入Redis
String jsonStr = JSONUtil.toJsonStr(redisData);
stringRedisTemplate.opsForValue().set(
RedisConstants.CACHE_SHOP_TYPE_KEY + typeId,
jsonStr
);
}
```
上述代码片段展示了如何将特定ID对应的店铺类型信息持久化至Redis中[^1]。
对于读取操作,则需先尝试从Redis获取对应键值;如果命中则解析返回给前端;未命中的情况下再回源查询真实库表记录,并更新最新版本到缓存层以便后续访问能快速响应。
```java
public ShopType queryWithLogicalExpire(Long id){
// 构造缓存Key
String key = RedisConstants.CACHE_SHOP_TYPE_KEY + id;
// 优先级最高的是直接从本地内存或更靠近用户的节点处取得所需资源
Object resultObj = localCache.getIfPresent(key);
if (resultObj != null && !isExpired(resultObj)){
return ((RedisData<ShopType>)resultObj).getData();
}
// 获取缓存中的json串
String typeJson = stringRedisTemplate.opsForValue().get(key);
if(StrUtil.isBlank(typeJson)) {
// 缓存穿透处理...
return null;
}
// 反序列化成对象
RedisData redisData = JSONUtil.toBean(typeJson, RedisData.class);
JSONObject data = JSONUtil.parseObj(redisData.getData());
ShopType shopType = BeanUtil.fillBeanWithData(data, new ShopType(), true);
// 判断是否已过期
LocalDateTime expireTime = redisData.getExpireTime();
if(expireTime.isAfter(LocalDateTime.now())) {
// 如果没过期就正常返回商品详情
return shopType;
} else{
// 已经过期了,删除旧版缓存条目
stringRedisTemplate.delete(key);
// 背景异步重构新缓存项
rebuildCacheOnBackground(id,key);
// 返回null 或者默认值/降级方案
return null;
}
}
private boolean isExpired(Object obj){
try{
RedisData<?> rd = (RedisData<?>)obj;
return rd.getExpireTime().isBefore(LocalDateTime.now());
}catch(Exception e){
log.error("判断缓存是否过期失败",e);
return false;
}
}
```
这段Java程序实现了带有逻辑过期机制的商品详情页缓存功能,在保证高性能的同时也兼顾了一定程度上的一致性和安全性。
当遇到缓存雪崩风险时,可以通过引入随机延迟、限流措施以及分布式锁等方式来缓解突发流量冲击带来的负面影响[^4]。
阅读全文
相关推荐









