java点赞功能
在电脑上 人气:0实现思路:
将点赞的数据先保存到redis中,然后定时同步到数据库
第一步:
在redis中创建二个hash 用于存储 用户点赞记录及记录点赞数
MAP_USER_LIKED :用户点赞的记录 key:记录id::用户id value:1
MAP_USER_LIKED_COUNT:记录点赞数 key: 记录id value:数量
第二步:
创建枚举类
@Getter public enum LikeStatusEnum { LIKE(1,"点赞"), UNLIKE(0,"取消点赞/未点赞"); private Integer code; private String msg; LikeStatusEnum(Integer code,String msg){ this.code = code; this.msg = msg; } }
@Getter public enum RedisHashEnum { MAP_USER_LIKED("MAP_USER_LIKED"), MAP_USER_LIKED_COUNT("MAP_USER_LIKED_COUNT"); private String value; RedisHashEnum(String value){ this.value =value; } }
第三步:
将实现类写好
@Service public class PostRedisServiceImpl implements PostRedisService { @Resource private RedisTemplate redisTemplate; @Autowired(required = false) public void setRedisTemplate(RedisTemplate redisTemplate){ RedisSerializer serializer = new StringRedisSerializer(); redisTemplate.setKeySerializer(serializer); redisTemplate.setValueSerializer(serializer); redisTemplate.setHashKeySerializer(serializer); redisTemplate.setHashValueSerializer(serializer); this.redisTemplate = redisTemplate; } /** * 点赞、取消点赞 * * @param recordId * @param userId */ @Override public void saveLikeRedis(String recordId, String userId,Integer status) { String key =recordId+"::"+userId; redisTemplate.opsForHash().put(RedisHashEnum.MAP_USER_LIKED,key, status); } /** * 从Redis中删除一条点赞数 * * @param recordId * @param userId */ @Override public void deleteLikeFromRedis(String recordId, String userId) { String key =recordId+"::"+userId; redisTemplate.opsForHash().delete(RedisHashEnum.MAP_USER_LIKED,key); } /** * 该记录 点赞加1 * * @param recordId */ @Override public void incrementLikedCount(String recordId) { redisTemplate.opsForHash().increment(RedisHashEnum.MAP_USER_LIKED_COUNT,recordId,1); } /** * 譔记录 点赞减1 * * @param recordId */ @Override public void decrementLikeCount(String recordId) { redisTemplate.opsForHash().increment(RedisHashEnum.MAP_USER_LIKED_COUNT,recordId,-1); } }
第四步提供接口:
/** * 进行点赞、取消点赞 * * @param vo */ @Override public Result addKudos(KudosVo vo) { if(vo == null){ return Result.error(ResponseMessage.PARAMERROR); } if("1".equals(vo.getStatus())){ // 点赞 postRedisService.saveLikeRedis(vo.getRecordId(),vo.getUserId(), LikeStatusEnum.LIKE.getCode()); // 记录+1 postRedisService.incrementLikedCount(vo.getRecordId()); }else if("0".equals(vo.getStatus())){ // 取消点赞 更新状态 postRedisService.saveLikeRedis(vo.getRecordId(),vo.getUserId(), LikeStatusEnum.UNLIKE.getCode()); // postRedisService.deleteLikeFromRedis(vo.getRecordId(),vo.getUserId()); // 记录 -1 postRedisService.decrementLikeCount(vo.getRecordId()); } return Result.success(ResponseMessage.SUCCESS); }
最后定时将redis 中的数据同步到数据库
/**每 5 分钟执行一次 * 将点赞人员同步到库中 * */ // @Transactional(rollbackFor =Exception.class) @Scheduled(cron = "0 */5 * * * ?") public void transLikdedFromRedis()throws IOException{ List<RedisLikedUserDTO> dtoList = getLikedUserFromRedis(); dtoList.stream().forEach(x->{ // 通过记录及人员id 查询 该 人员是否点赞 LambdaQueryWrapper<WorkCircleRecord> queryWrapper = new LambdaQueryWrapper<>(); queryWrapper.eq(WorkCircleRecord::getDeleteIf,true); queryWrapper.eq(WorkCircleRecord::getId,x.getRecordId()); queryWrapper.like(WorkCircleRecord::getWorkKudosUserIds,x.getUserId()); WorkCircleRecord record = workCircleRecordMapper.selectOne(queryWrapper); // 点赞 if(record == null&&"1".equals(x.getStatus())){ // 根据记录id 查询 LambdaQueryWrapper<WorkCircleRecord> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WorkCircleRecord::getDeleteIf,true); wrapper.eq(WorkCircleRecord::getId,x.getRecordId()); WorkCircleRecord workCircleRecord = workCircleRecordMapper.selectOne(wrapper); if(workCircleRecord != null){ // 没有此人员 添加 if(StringUtils.isBlank(workCircleRecord.getWorkKudosUserIds())){ // 没有点赞人员 workCircleRecord.setWorkKudosUserIds(x.getUserId()); SysUser user = sysUserMapper.selectById(x.getUserId()); if(user !=null){ workCircleRecord.setWorkKudosUser(user.getRealname()); } }else { // 有点赞人员 String userIds = x.getUserId()+","+workCircleRecord.getWorkKudosUserIds(); workCircleRecord.setWorkKudosUserIds(userIds); SysUser user = sysUserMapper.selectById(x.getUserId()); String userNames = user.getRealname()+workCircleRecord.getWorkKudosUser(); workCircleRecord.setWorkKudosUser(userNames); } workCircleRecordMapper.updateById(workCircleRecord); } }else if("0".equals(x.getStatus())) { // 有记录 并取消点赞 // 根据记录id 查询 LambdaQueryWrapper<WorkCircleRecord> wrapper = new LambdaQueryWrapper<>(); wrapper.eq(WorkCircleRecord::getDeleteIf,true); wrapper.eq(WorkCircleRecord::getId,x.getRecordId()); WorkCircleRecord workCircleRecord = workCircleRecordMapper.selectOne(wrapper); // 将此点赞人员去除 if(workCircleRecord !=null){ SysUser user = sysUserMapper.selectById(x.getUserId()); List<String> userIds = Arrays.asList(workCircleRecord.getWorkKudosUserIds().split(",")); List<String> userNames =Arrays.asList(workCircleRecord.getWorkKudosUser().split(",")); userIds.remove(x.getUserId()); userNames.remove(user.getRealname()); workCircleRecord.setWorkKudosUserIds(String.join(",",userIds)); workCircleRecord.setWorkKudosUser(String.join(",",userNames)); workCircleRecordMapper.updateById(workCircleRecord); } } }); }
/**获取 所有点赞的人员 * */ public List<RedisLikedUserDTO> getLikedUserFromRedis() throws IOException{ List<RedisLikedUserDTO> dtoList = new ArrayList<>(); // 通过游标获取所有键值对 Cursor<Map.Entry<Object,Object>> cursor = redisTemplate.opsForHash().scan(RedisHashEnum.MAP_USER_LIKED.getValue(),ScanOptions.NONE); while (cursor.hasNext()){ Map.Entry<Object,Object> map = cursor.next(); String key = map.getKey().toString(); String[] split = key.split("::"); RedisLikedUserDTO dto = new RedisLikedUserDTO(); dto.setRecordId(split[0]); dto.setUserId(split[1]); dto.setStatus(Integer.parseInt(map.getValue().toString())); dtoList.add(dto); // 将redis 中的记录删除 redisTemplate.opsForHash().delete(RedisHashEnum.MAP_USER_LIKED.getValue(),key); } cursor.close(); return dtoList; }
/**每 5 分钟执行一次 * 将点赞数同步到库中 * */ @Transactional(rollbackFor =Exception.class) @Scheduled(cron = "0 */5 * * * ?") public void transLikedCountFromRedis() throws IOException{ // 获取所有的点赞数 List<RedisLikeCountDTO> dtoList = getLikedCountFromRedis(); // 获取所有的记录id List<String> recordIdList = dtoList.stream().map(x->x.getRecordId()).collect(Collectors.toList()); if(CollectionUtils.isNotEmpty(recordIdList)){ List<WorkCircleRecord> recordList = workCircleRecordMapper.selectBatchIds(recordIdList); if(CollectionUtils.isNotEmpty(recordList)){ // 通过id 匹配 dtoList.stream().forEach(x->{ recordList.stream().forEach(k->{ if(x.getRecordId().equals(k.getId())){ Integer num = x.getCount()+k.getWorkKudos(); if(num<0){ k.setWorkKudos(0); }else { k.setWorkKudos(num); } workCircleRecordMapper.updateById(k); } }); }); } } }
/** 取出所有的点赞数 * */ public List<RedisLikeCountDTO> getLikedCountFromRedis() throws IOException { List<RedisLikeCountDTO> dtoList = new ArrayList<>(); Cursor<Map.Entry<Object,Object>> cursor= redisTemplate.opsForHash().scan(RedisHashEnum.MAP_USER_LIKED_COUNT, ScanOptions.NONE); while (cursor.hasNext()){ Map.Entry<Object,Object> map = cursor.next(); // 获取 点赞数 String key = map.getKey().toString(); RedisLikeCountDTO dto = new RedisLikeCountDTO(); dto.setRecordId(key); dto.setCount(Integer.parseInt(map.getValue().toString())); dtoList.add(dto); redisTemplate.opsForHash().delete(RedisHashEnum.MAP_USER_LIKED_COUNT,key); } cursor.close(); return dtoList; }
加载全部内容