java项目实现--论坛社交之点赞、关注业务(一)

发布于:2022-12-22 ⋅ 阅读:(453) ⋅ 点赞:(0)

前言:最近也是在写一个项目,我负责的模块涉及类似论坛的社交圈子模块,在这里做个总结吧。能帮助别人当然更好,毕竟我是一个有着高尚节操的社会主义新青年!

一、功能目的

1、 实现社交目的,用户可以给其他用户发布的动态点赞、收藏、评论、转发等功能。

2、用户之间可以互相关注

二、业务思路

1、由于类似业务所需要的场景,大部分都需要频繁访问数据库,以及考虑高并发等因素;

2、业务流程并不复杂,怎么合理的存储数据相较而言比较麻烦了。

三、给大佬们喂屎!!!【手动狗头】

1、数据库设计

(1)、动态表

 (2)、用户表

 (3)、用户互相关注表

 (4)、评论表

 2、业务代码实现

  (1)、点赞功能实现

鄙人的想法:

1、需要考虑的是,点赞这种功能肯定是不能直接访问mqsql数据库中的,操作过于频繁,会导致数据库的拥堵,需要将它存储到redis缓存中。然后做一个定时任务,将数据定时批量存储到数据库中;

2、类似【知乎】等之类的社交平台,用户对你的动态或者某条评论进行点赞时,被点赞的用户也会收到“某某用户喜欢了你的某条动态”这样的业务功能。由于是个练手项目时间也比较紧张,这里只是更新了点赞数量,这个消息功能倒还没有做。但类似参考下面的【关注】业务功能,使用mq对其进行实现,也不是特别“懒”。

3、还需要注意的是,点赞之后再次点击就会取消点赞。

废话不多说了,任尔麒麟云中现,呼吸一剑开天门!(咳咳、比赛触发我的灵感)

    a、controller     


    /**
     * 点赞功能
     */
    @PostMapping("/likeDynacim/{dynamicId}")
    @ApiOperation("动态点赞")
    public CommonResult thumbDynamic(@PathVariable Integer dynamicId, HttpServletRequest request) {
        //这是对当前登录页面做一个登录判断,若是没有登录,则不能进行一键三连
        Integer userId = (Integer) getUserId();
        if (Objects.isNull(userId)) {
            return CommonResult.failure("用户未登录!");
        } else {
           //调用业务层点赞方法
            Boolean status = userLikeDetailService.likeDynamic(userId, dynamicId);
            return CommonResult.success(status);
        }
    }

 b、serviceImpl 层

@Service
public class UserLikeDetailServiceImpl extends ServiceImpl<UserLikeDetailMapper, UserLikeDetail> implements IUserLikeDetailService {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private RabbitTemplate rabbitTemplate;

    @Resource
    private UserLikeDetailMapper userLikeDetailMapper;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private LikeUserConsumer likeUserConsumer;

    /**
     * 点赞动态
     */
    @Override
    public Boolean likeDynamic(Integer userID, Integer dynamicID) {
        //1、判断该用户有没有点赞过
        Boolean member = redisTemplate.opsForSet()
                .isMember(RedisConstant.LIKE_DYNAMIC + ":" + dynamicID, userID);
        System.out.println("member=======>" + member);
        //2、判断是否点赞过

        if (member) {
            //3、如果存在 则取消点赞  删除这个值
            redisTemplate.opsForSet().remove(RedisConstant.LIKE_DYNAMIC + ":" + dynamicID, userID);
        }else {
            //4、不存在则将点赞加入这个set集合中
            redisTemplate.opsForSet().add(RedisConstant.LIKE_DYNAMIC + ":" + dynamicID, userID);
        }

        //----------------------------------------------------------------------------------------------
        Set<Integer> cacheSet = redisUtil.getCacheSet(RedisConstant.LIKE_DYNAMIC);
        System.out.println("cacheSet==================>"+cacheSet);

        return redisTemplate.opsForSet()
                .isMember(RedisConstant.LIKE_DYNAMIC + ":" + dynamicID, userID);
    }

定义的存储key常量名 

**
 * redis key 名常量
 */
public interface RedisConstant {


    /**
     * 动态 点赞 key
     */
    public static final String LIKE_DYNAMIC = "likeDynamic";

    public static final String LIKE_DYNAMIC_KEY_NAME  = "likeDynamic*";

}

redis存储的数据结构

 -------------到这里了,我们点赞数据的存储就是完成了,假如用户再次点击,redis缓存中的set集合也会将该动态点赞用户的id删除掉。后面我们的任务就是开启一个定时任务定时的将redis数据存储到mysql数据库中做持久化。

/**
 * 定时任务类
 */
@Component
@Slf4j
public class Task {

    @Resource
    private RedisTemplate redisTemplate;

    @Resource
    private IUserLikeDetailService userLikeDetailService;

    @Resource
    private RedisUtil redisUtil;

    @Resource
    private IDynamicService dynamicService;

    /**
     * 将动态的评论数量 、点赞数量等存储到数据库中
     * id--->数量
     */
    @Scheduled(cron = "0/3 * * * * ?")
    public void initThumbs() {
        redisTemplate.execute(new RedisCallback<Object>() {
            @Override
            public Object doInRedis(RedisConnection redisConnection) throws DataAccessException {
                //1、根据键值常量获取点赞集合
                Set<byte[]> likeDynamicSet = redisConnection.keys("likeDynamic*".getBytes());
                //2、new 一个集合  用于分装数据
                List<Dynamic> dynamics = new ArrayList<>();
                //3、遍历集合分别获取对应的键值
                for (byte[] b : likeDynamicSet) {
                    //4、用于操作redis中的key
                    String bKey = new String(b);
                    //5、通过key来获取对应的value
                    Set<Integer> cacheSet = redisUtil.getCacheSet(bKey);
                    int i = bKey.lastIndexOf(":");
                    // 动态id
                    Integer dynamicId = Integer.valueOf(bKey.substring(i + 1));
                    // 点赞数
                    int dyPraiseNum = cacheSet.size();
                    //6、封装数据
                    Dynamic dynamic = new Dynamic();
                    dynamic.setId(dynamicId);
                    dynamic.setDyPraiseNum(dyPraiseNum);
                    //7、将该对象添加到集合中
                    dynamics.add(dynamic);
                }
                //8、批量更新
                boolean b = dynamicService.updateBatchById(dynamics);
                log.info("--------------开始定时存储点赞数据------------");
                return b;
            }
        });
    }

 到此为止,我们动态的点赞业务就完成了。还剩一点后面再写,今天过节,对于我这瓢泼在外的IT民工,也要对自己好一点。

今天中秋,祝工友们中秋快乐,身体健康。


网站公告

今日签到

点亮在社区的每一天
去签到