当前位置:网站首页>10、Redis实现点赞(Set)和获取总点赞数
10、Redis实现点赞(Set)和获取总点赞数
2022-07-31 02:36:00 【A snicker】
实现点赞

不用写数据访问层,直接在Service层写即可。
1、创建RedisKeyUtil工具类生成key:
public class RedisKeyUtil {
private static final String SPLIT = ":";
private static final String PREFIX_ENTITY_LIKE = "like:entity";
// 某个实体的赞
// like:entity:entityType:entityId -> set(userId)
public static String getEntityLikeKey(int entityType, int entityId) {
return PREFIX_ENTITY_LIKE + SPLIT + entityType + SPLIT + entityId;
}
}
2、LikeService
@Service
public class LikeService {
@Autowired
private RedisTemplate redisTemplate;
// 点赞,查看该用户userId是否在集合里,没在集合里,加进去,即点赞;在集合里,取消点赞,remove掉
public void like(int userId, int entityType, int entityId) {
String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
boolean isMember = redisTemplate.opsForSet().isMember(entityLikeKey, userId);
if (isMember) {
redisTemplate.opsForSet().remove(entityLikeKey, userId);// 取消点赞
} else {
redisTemplate.opsForSet().add(entityLikeKey, userId);
}
}
// 查询某实体点赞的数量,看集合里有多少个userId
public long findEntityLikeCount(int entityType, int entityId) {
String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
return redisTemplate.opsForSet().size(entityLikeKey);
}
// 查询某人对某实体的点赞状态,看某userId是否在集合里,返回1点赞了,返回0没点赞(点踩可以返回-1)
public int findEntityLikeStatus(int userId, int entityType, int entityId) {
String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
return redisTemplate.opsForSet().isMember(entityLikeKey, userId) ? 1 : 0;
}
}
3、LikeController
@Controller
public class LikeController {
@Autowired
private LikeService likeService;
@Autowired
private HostHolder hostHolder;
@RequestMapping(path = "/like", method = RequestMethod.POST)
@ResponseBody
public String like(int entityType, int entityId) {
User user = hostHolder.getUser();
// 点赞
likeService.like(user.getId(), entityType, entityId);
// 重新计算数量
long likeCount = likeService.findEntityLikeCount(entityType, entityId);
// 重新计算状态
int likeStatus = likeService.findEntityLikeStatus(user.getId(), entityType, entityId);
Map<String, Object> map = new HashMap<>();
map.put("likeCount", likeCount);
map.put("likeStatus", likeStatus);
return CommunityUtil.getJSONString(0, null, map);
}
}
4、异步请求,discuss.js
function like(btn, entityType, entityId) {
$.post(
CONTEXT_PATH + "/like",
{
"entityType":entityType,"entityId":entityId},
function(data) {
data = $.parseJSON(data);
if(data.code == 0) {
$(btn).children("i").text(data.likeCount);
$(btn).children("b").text(data.likeStatus==1?'已赞':"赞");
} else {
alert(data.msg);
}
}
);
}
获取总点赞数
1、改key拼接工具类RedisKeyUtil
private static final String PREFIX_USER_LIKE = "like:user";
// 某个用户的被点赞总数, value是Object->强转成Integer->intValue()转成int型
// like:user:userId -> int
public static String getUserLikeKey(int userId){
return PREFIX_USER_LIKE + SPLIT + userId;
}
2、LikeService,编程式事务
保证事务性,一次点赞两处增加,编程式事务
public void like(int userId, int entityType, int entityId, int entityUserId) {
// 保证事务性,一次点赞两个增加,编程式事务
redisTemplate.execute(new SessionCallback() {
@Override
public Object execute(RedisOperations operations) throws DataAccessException {
String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
String userLikeKey = RedisKeyUtil.getUserLikeKey(entityUserId);
// 查询要在事务之前,不能放在事务里面,否则事务提交之后才执行。
boolean isMember = operations.opsForSet().isMember(entityLikeKey, userId);
operations.multi();
if (isMember) {
operations.opsForSet().remove(entityLikeKey, userId);// 取消点赞
operations.opsForValue().decrement(userLikeKey);// 减少实体的被点赞数
}else{
operations.opsForSet().add(entityLikeKey, userId);// 点赞
operations.opsForValue().increment(userLikeKey);// 增加实体的被点赞数
}
return operations.exec();
}
});
}
查询某个用户获得的赞的总数
// 查询某个用户获得的赞的总数
public int findUserLikeCount(int userId) {
String userLikeKey = RedisKeyUtil.getUserLikeKey(userId);
Integer count = (Integer) redisTemplate.opsForValue().get(userLikeKey);
return count == null ? 0 : count.intValue();
}
边栏推荐
- BAT卖不动「医疗云」:医院逃离、山头林立、行有行规
- f.grid_sample
- ShardingJDBC usage summary
- CMOS和TTL的区别?
- Basic learning about Redis related content
- 力扣刷题之有效的正方形(每日一题7/29)
- Force buckled brush the stairs (7/30)
- Brute Force/Adjacency Matrix Breadth First Directed Weighted Graph Undirected Weighted Graph
- [1154]如何将字符串转换为datetime
- Between two orderly array of additive and Topk problem
猜你喜欢

Inter-vlan routing + static routing + NAT (PAT + static NAT) comprehensive experiment

Basic introduction to ShardingJDBC

用户交互+格式化输出

CMOS和TTL的区别?

leetcode-399: division evaluation

Problems that need to be solved by the tcp framework

Coldfusion file read holes (CVE - 2010-2861)

【Bank Series Phase 1】People's Bank of China

Nacos

f.grid_sample
随机推荐
The principle of complete replication of virtual machines (cloud computing)
Can an inexperienced college graduate switch to software testing?my real case
LeetCode 1161 The largest element in the layer and the LeetCode road of [BFS binary tree] HERODING
The difference between link and @import
局域网电脑硬件信息收集工具
Intel's software and hardware optimization empowers Neusoft to accelerate the arrival of the era of smart medical care
MPPT太阳能充放电控制器数据采集-通过网关采集电池电压容量电量SOC,wifi传输
Drools WorkBench的简介与使用
C language applet -- common classic practice questions
SQL注入 Less54(限制次数的SQL注入+union注入)
Installation, start and stop of redis7 under Linux
STM32CUBEMX develops GD32F303 (11) ---- ADC scans multiple channels in DMA mode
mysql 视图
Coldfusion file read holes (CVE - 2010-2861)
自动化办公案例:如何自动生成期数据?
Path and the largest
二层广播风暴(产生原因+判断+解决)
Unity界面总体介绍
Real-time image acquisition based on FPGA
cudaMemcpy学习笔记