首页 > 其他分享 ># 干货场景 - 我的被点赞评论列表

# 干货场景 - 我的被点赞评论列表

时间:2024-12-12 18:58:47浏览次数:14  
标签:like CommentLikeResp 用户 列表 干货 评论 点赞

# 干货场景 - “我的评论点赞列表”

在这里插入图片描述

介绍

我们通常能在一个交互平台看到我们的优质评论被点赞的信息, 但这看似简单的效果, 实则却是疯狂的复杂结构, 接下来教你如何简单完成这一需求

我们先来看最终的显示效果

在这里插入图片描述

从这里我们可以看到几个主要信息

  1. 右边 >> 我的评论
  2. 左边 << 点赞的信息
  3. 左边 << 点赞的时间

由此我们可以获得这个表的设计 我的评论点赞列表 comment_like

类型描述
comment_idINT我的评论(外键,关联评论表)
user_idINT点赞的用户 (外键,关联用户表)
created_atDATETIME点赞时间

该表关系为一对多(实质为多对多), 表示 一个评论被多个用户点赞, 为了方便演示, 我们再补全 评论用户 这两张表

用户评论表

类型描述
comment_idINT主键
created_atDATETIME发送评论时间
statusTINYINT评论状态 0-撤回 1-正常 2-违规 3-待审核
like_numINT点赞量
u_idINT外键, 绑定发评论的用户
iss_idINT评论的视频 (作品)

用户表

类型描述
u_idINT主键
nameVARCHAR用户昵称
pictureVARCHAR图片URL
. . .

开始

请求

  1. 首先进入这个页面, 获取这个数据, 就需要前端传递这个用户的编号
    /comments/{u-id}/comment-likes 表示 : 当前用户发布所有评论 的点赞列表

  2. 后端通过 前端传递的 u-id 就可以在评论表中 连接 发评论的用户, 过滤出当前用户的所有评论, 但单这样我们是拿不到以下数据的

    预期效果
    在这里插入图片描述

  3. 也就是说, 我们要查询的主表不是 评论表, 而是评论点赞列表, 我们需要通过该列表的评论外键 comment_id, 去连接发评论的用户 = 前端传递的 {u-id}

    select (省略) 
    	from comment_like 点赞列表 
    		join comment 评论
    	 		on 点赞列表.cm_id = 评论.cm_id 
              where 评论.u_id = #{u_id} -- 前端传递的 当前用户编号
              	order by 点赞列表.created_at
    		
    

响应

正确处理请求后, 我们要考虑的就是响应格式了

在这里插入图片描述

我们从图片中分析响应格式, 其中应该包含数组嵌套对象, 对象嵌套数组, 那么一般的响应格式是满足不了我们的, 就像上方 sql 更不满足图中的要求, 那我们就不得不避开一般的响应格式, 使用 “DTO

DTO 是什么?

就是为了定义和封装 响应数据格式请求数据格式 而创建的类。

  • 我们先根据图片慢慢分析, 从图片中获取的信息

    • 用户 >> 头像
    • 用户 >> 昵称
    • 评论 >> 内容
    • 最近的点赞时间
  • 根据梳理结合图片, 可以明白返回格式首先是一个数组, 并且数组里有多个对象, 对象包含

    1. 最新的点赞时间 created_at, 从多个点赞的用户当中选出最早点赞的

      示例 sql 返回的数据

      点赞的用户点赞的时间 create_at**点赞的用户 **u_id我的评论 comment_id
      第一个2020年9月10日 9:16:0010011
      第二个2020年9月10日 9:16:0210021
      第三个 (这个是评论1最新的点赞!)2020年9月10日 9:16:0310031
      第一个2020年9月10日 9:17:0010012
      第二个 (这个是评论2最新的点赞!)2020年9月10日 9:17:0210022

      ​ 表格示例中, 直到下一个评论 前 我的评论 一直不变, 而点赞的用户一直在变, 所以数组中的单个对象就 对应 着单个我的评论, 而点赞我的用户则是一个集合, 由此可得以下格式

    2. 对象里嵌套 点赞的用户对象, 其中包含用户的信息

      {
           "code": 200,
           "msg": "success",
           "data": [
                {
                     "created_at": "2024年8月12日 11:49",
                     "users": [
                          {
                               "uId": 1,
                               "name": "懒懒不想想"
                          },
                          {
                               "uId": 2,
                               "name": "宇宙最帅莫漓酱"
                          }
                     ],
                     "comment": {
                          "cmId": 1,
                          "content": "好可爱",
                          "likeNum": 12
                     }
                }
           ]
      }
      
    3. 定义这三个表对应的DTO对象 (DTO 对象后缀一般为 Response, Request)

      // 评论点赞列表DTO
      public class CommentLikeResp {
          private String creTime;
          private CommentResponse comment;
          private List<UserResponse> users;
      
          // Getters and Setters
      }
      
      // 我的评论DTO
      public class CommentResp {
          private Integer cmId;
          private String content; // 需要从 UserComment 中获取
          private Integer likeNum;
      
          // Getters and Setters
      }
      
      // 点赞的用户DTO
      public class UserResp {
          private Integer uId;
          private String name;
      
          // Getters and Setters
      }
      
    4. 编写 查询所有用户评论点赞列表的 sql 语句

      @Mapper
      public interface CommentLikeMapper {
          @Select(""" 
                  select * 
                  	  from comment_like as 点赞列表 
      			join comment as 评论
      	 			on 点赞列表.cm_id = 评论.cm_id 
      	          	where 评论.u_id = #{uId} 
                			order by 点赞列表.created_at
                  """)
          List<CommentLike> getCommentLikesByUserId(Integer uId);
      }
      
    5. 事务层进行格式封装

      public List<CommentLikeResp> getCommentLikesByUser Id(Integer uId) {
           List<CommentLike> likes = commentLikeMapper.getCommentLikesByUId(uId);
           List<CommentLikeResp> respList = new ArrayList<>();
           Map<Integer, CommentLikeResp> respMap = new HashMap<>();
      
           for (CommentLike like : likes) {
                // 获取或创建 CommentLikeResp 对象
                CommentLikeResp response = respMap.get(like.getComment().getId());
                if (response == null) {
                     // 创建新的 CommentResp 对象
                     CommentResp commentResponse = new CommentResp(
                          like.getComment().getId(),
                          like.getComment().getContent(),
                          like.getComment().getLikeNum() // 假设 Comment 类有这个方法
                     );
      
                     // 创建新的 CommentLikeResp 对象
                     response = new CommentLikeResp(
                          like.getCreatedAt(),
                          new ArrayList<>(), // 初始化用户列表
                          commentResponse
                     );
      
                     // 将新创建的响应对象放入 Map 中
                     respMap.put(like.getComment().getId(), response);
                }
      
                // 添加用户信息
                UserResp userResponse = new UserResp(like.getUser ().getId(), like.getUser ().getName());
                response.getUsers().add(userResponse);
           }
      
           // 将 Map 中的所有响应对象转换为列表
           respList.addAll(respMap.values());
      
           return respList;
      }
      

      以下是逐步拆解 (实际上sql 返回就是点赞列表, 只是格式不符, 所以该方法仅是为了返回一个格式而已)

      主要思路 :

      ​ 通过已有点赞列表获取DTO对象, 但实际上DTO对象最初并没有数据 而是通过后续的if 条件一步步生成的 而获取DTO对象是为了确保当前评论下有对应的点赞用户而不受乱序影响 (如果你读懂了这句段落接下来就可以不用看了, 你已经会啦)


      1. 遍历点赞记录

      for (CommentLike like : likes) {
      

      目的:
      遍历所有点赞记录,将每条记录根据其评论ID分组,同时将点赞用户信息添加到对应的分组中。


      2. 获取或创建 CommentLikeResp 对象

      CommentLikeResp response = respMap.get(like.getComment().getId());
      if (response == null) {
          // 创建新的 CommentResp 对象
          CommentResp commentResponse = new CommentResp(
              like.getComment().getId(),
              like.getComment().getContent(),
              like.getComment().getLikeNum()
          );
      
          // 创建新的 CommentLikeResp 对象
          response = new CommentLikeResp(
              like.getCreatedAt(),
              new ArrayList<>(), // 初始化用户列表
              commentResponse
          );
      
          // 将新创建的响应对象放入 Map 中
          respMap.put(like.getComment().getId(), response);
      }
      

      目的:
      对每条点赞记录,判断是否已经有一个对应的 CommentLikeResp 对象存在:

      1. 如果存在: 直接获取,避免重复创建对象。
      2. 如果不存在:
        • 创建 CommentResp 对象: 封装评论的信息(评论ID、内容、点赞数)。
        • 创建 CommentLikeResp 对象: 封装评论和点赞相关的信息,包括点赞时间(createdAt)和一个空的用户列表。
        • 存入 respMap 将新创建的 CommentLikeResp 对象以评论ID为键存入映射,方便后续操作。

      3. 添加用户信息到 CommentLikeResp

      UserResp userResponse = new UserResp(like.getUser().getId(), like.getUser().getName());
      response.getUsers().add(userResponse);
      

      目的:
      将当前点赞记录中的用户信息(用户ID、用户名)封装成 UserResp 对象,并添加到对应的 CommentLikeResp 对象的用户列表中。

      • UserResp 是一个 DTO 类,用于封装用户信息(用户ID、用户名)。
      • response.getUsers().add(userResponse) 将用户添加到当前评论的用户列表中,表示该用户对这条评论点了赞。

      4. 将分组结果转换为列表

      respList.addAll(respMap.values());
      

      目的:
      遍历 respMap 中的所有 CommentLikeResp 对象,将其转换为列表并存入 respList

      • respMap.values() 获取所有分组后的 CommentLikeResp 对象。
      • 最终的 respList 包含按评论分组的点赞记录,符合预期的返回格式。

剩下的只显示两个或一个用户就简单了,

End

如果这篇文章帮到你, 帮忙点个关注呗, 点赞或收藏也行鸭 ~ (。•ᴗ-)✧

在这里插入图片描述
^ '(இ﹏இ`。)

标签:like,CommentLikeResp,用户,列表,干货,评论,点赞
From: https://blog.csdn.net/2403_89128801/article/details/144385630

相关文章

  • Python3 insloader库爬取博主视频粉丝量,点赞,互动率,国家等信息
    写在题前:之前搞Java的,今天部门的人给了我一批视频链接,问问有没有办法爬出来这一批视频链接的博主的粉丝量,以及该视频的互动率等信息。经过一番探索之后了解了insloader库。真不不得不感叹python的强大。 之前给代码把:importinstaloaderfromurllib.parseimporturlpars......
  • 干货分享:可以免费问答的几个GPT网站
    ​ 1、ChatGPT......
  • Python序列的应用(七):序列、列表
    前言:在Python编程语言中,序列(Sequence)是一种基本且核心的数据结构,它允许我们以有序的方式存储和操作数据。序列可以包含不同类型的元素,并且支持通过索引来访问和修改这些元素。在Python中,最常见的序列类型包括列表(List)、元组(Tuple)、字符串(String)等。这些序列类型在数据处理、......
  • python语言基础之列表(一)
    目录什么是列表列表的创建与删除通过赋值直接创建列表创建空列表创建数值列表删除列表访问列表元素遍历列表for循环遍历列表for循环与enumerate()函数实现列表更新添加元素修改元素删除元素根据索引删除根据元素值删除什么是列表列表是由一系列按特定顺序......
  • .m3u8 格式本质上是 HLS 协议中流媒体传输的播放列表文件,它定义了视频或音频流的结构
    .m3u8 格式.m3u8是一种扩展的M3U文件格式,通常用于播放列表和流媒体文件,特别是在HTTPLiveStreaming(HLS)中应用广泛。与传统的.m3u文件相比,.m3u8文件采用UTF-8编码,支持更多的国际字符,同时广泛应用于网络流媒体和现代设备中。主要特点与应用:编码格式:.m3u8 使用 ......
  • Windows Media Player 支持多种播放列表文件格式,主要包括以下几种:
    .m3u、.wpl、.asx、.pls和.mpcpl播放列表格式的对比表,展示它们的主要区别:特性.m3u.wpl.asx.pls.mpcpl格式文本文件(简单列表)XML文件XML文件文本文件(键值对格式)XML文件用途播放音频文件(本地或网络资源)播放音频/视频文件,支持元数据和设置流媒体播放列......
  • ACL与Prefix List(前缀列表)
    匹配工具一般搭配其他操作,可实现NAT,路由策略,策略路由,MQC,流量过滤等操作通配符掩码我们都知道子网掩码的1是精确匹配,1是大致匹配,1必须连续我们也知道反掩码的1是大致匹配,0是精确匹配,0必须连续那么通配符掩码其实和反掩码很像,ta的0也是精确匹配,1也是大致匹配,但与前两者不同......
  • 【鸿蒙 ArkTS 开发】网络请求HTTP并渲染列表展示
    1.页面布局和网络请求(展示产品信息)在这个页面中,我们会从网络获取产品数据,并使用List组件展示产品信息。product_list_page.etsimportui;import@ohos.net.http;importohos.agp.components.List;importohos.agp.components.Text;importohos.agp.components.Image;......
  • 在 Windows 中,您可以通过 CMD 或 PowerShell 实现对 Windows Media Player 播放列表的
    在Windows中,您可以通过CMD或PowerShell实现对WindowsMediaPlayer播放列表的管理和操作。不过,直接通过这些命令行工具来创建媒体库播放列表、媒体流等功能是有一定局限的,因为WindowsMediaPlayer并没有直接的命令行接口来创建播放列表。尽管如此,我们可以使用一些间接......
  • 命令行通过 mpv.exe 播放多个视频文件,您可以通过以下几种方式来创建视频播放列表。2.
    命令行通过mpv.exe播放多个视频文件,您可以通过以下几种方式来创建视频播放列表。1.直接在命令行中指定多个视频文件你可以在命令行中一次性指定多个视频文件,MPV会按顺序播放它们。例如:bashCopyCodempvvideo1.mp4video2.mp4video3.mp4这将依次播放video1.mp4、video2......