内容一:选择的数据结构为哈希Hash!!
内容二:文章的维度~存储文章被点赞多的用户
Constant中增加一个key
public static String RedisArticlePraiseHashKey = "SpringBootRedis:Hash:Article:Praise:V2";
PraiseService.java:往db中插入数据后就要再调用cachePraiseOn函数
//点赞文章
@Transactional(rollbackFor = Exception.class)
public Boolean praiseOn(PraiseDto dto) throws Exception{
final String recordKey= Constant.RedisArticlePraiseUser+dto.getArticleId()+dto.getUserId();
//判断当前用户是否已点赞当前的文章(判断当前用户是否可以点赞该文章) - 控制并发操作的风险(并发安全的一种 - 分布式锁的体现)
Boolean canPraise=redisTemplate.opsForValue().setIfAbsent(recordKey,1);
//redisTemplate.hasKey(recordKey); //压测过后会发现,这种写法是有并发安全性的问题.
if (canPraise){
//将点赞的数据插入到db
ArticlePraise entity=new ArticlePraise(dto.getArticleId(),dto.getUserId(),DateTime.now().toDate());
int res=praiseMapper.insertSelective(entity);
if (res>0){
//叠加当前文章的点赞总量
articleMapper.updatePraiseTotal(dto.getArticleId(),1);
//缓存点赞的相关信息
this.cachePraiseOn(dto);
}
}
return true;
}
//缓存点赞相关的信息
private void cachePraiseOn(final PraiseDto dto) throws Exception{
HashOperations<String,String,Set<Integer>> praiseHash=redisTemplate.opsForHash();
//记录点赞的明细记录(文章的维度):文章id -> 点赞过该文章的用户id列表 (历史)
Set<Integer> uIds=praiseHash.get(Constant.RedisArticlePraiseHashKey,dto.getArticleId().toString());
//if (uIds==null || !uIds.isEmpty()){
if (uIds==null || uIds.isEmpty()){
uIds= Sets.newHashSet();
}
uIds.add(dto.getUserId());
praiseHash.put(Constant.RedisArticlePraiseHashKey,dto.getArticleId().toString(),uIds);
}