在数据库中选出互相关注的两名用户 | 青训营笔记

113 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 9 天

问题背景

在昨晚的直播答疑中,青训营项目讲解老师对之前项目大文档中的很多问题进行了解释与答疑,其中对于项目接口文档中的好友列表接口进行了详细的讲解与展示,由于接口文档以及好友列表功能描述的变化,所以我也需要对相应的结构体及其方法进行调整。

接口实现

*好友定义:首先就是好友定义的变化,官方文档将好友的定义修改为了互相关注的用户*

在之前的开发过程中,我使用了关系型数据库来存储各个用户之间的关注信息,数据库名称及字段信息如下图所示:

image.png

其中对于每一行数据,表示了 id 为 user_info_id 的用户关注了 id 为 follow_id 的用户,那么对于 user_id 为 id 的用户,她的好友就是与他互相关注的用户,由此,我们很容易地联想到了可以使用自关联来实现,那么我们可以写出相应的 SQL 语句:

SELECT 
    a.user_info_id 
FROM 
    user_relations a 
JOIN 
    user_relations b 
ON 
    a.user_info_id  = b.follow_id 
    AND a.follow_id = b.user_info_id
    AND a.follow_id = id

但是我们不难发现,这样子筛选出来的用户 id 的所有好友的 user_info_id 信息,之后,我们可以将上述语句作为子查询语句,来筛选出相应的 user_info,相应的 GoLang 代码如下所示:

if err := DB.Raw("SELECT * FROM user_infos WHERE user_infos.id IN (SELECT a.user_info_id FROM user_relations a JOIN user_relations b ON a.user_info_id  = b.follow_id AND a.follow_id = b.user_info_id  AND a.follow_id = ?)", id).Scan(userList).Error; err != nil {
   return err
}

这样我们便可以查询出来 id 用户的所有消息啦。

image.png

接下来便是返回相应的 Friend 列表,在新更新的接口说明文档中,我们可以发现,Friend 结构体与 User_INFO 结构体十分相似,为了提高代码的复用率,我们可以如下定义 Friend 结构体:

type Friend struct {
   UserInfo
   Avatar  string `json:"avatar"`
   Message string `json:"message"`
   MsgType int64  `json:"msg_type"`
}

这样,这样我们便可以复用 UserInfo 的相关的代码,然后再将获得的 user_list 封装并补充相应的 Message 和 MsgType

最后感谢工作人员昨晚的答疑解惑