day04-圈子功能实现

本文详细介绍了如何实现社交圈子功能,包括抽取common工程、圈子功能的设计与实现、好友关系数据、查询好友动态的接口服务,以及统一校验token、发布动态和查询推荐动态的流程。涉及到的技术包括MyBatis、Java、Spring Boot、MongoDB、Dubbo和Redis。
摘要由CSDN通过智能技术生成

课程说明

  • 抽取common工程
  • 圈子功能说明
  • 圈子技术实现
  • 圈子技术方案
  • 圈子实现发布动态
  • 圈子实现好友动态
  • 圈子实现推荐动态

1、抽取common工程

在项目中一般需要将公用的对象进行抽取放到common工程中,其他的工程依赖此工程即可。下面我们将sso以及server工程中的公用的对象进行抽取。

1.1、创建my-tanhua-common工程

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>my-tanhua</artifactId>
        <groupId>cn.itcast.tanhua</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>my-tanhua-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
        </dependency>
    </dependencies>

</project>

1.2、通用枚举

将SexEnum枚举移动至common工程,并且后续创建的枚举也要放到次工程中,以达到公用的目的。

package com.tanhua.common.enums;

import com.baomidou.mybatisplus.core.enums.IEnum;

public enum SexEnum implements IEnum<Integer> {
   

    MAN(1,"男"),
    WOMAN(2,"女"),
    UNKNOWN(3,"未知");

    private int value;
    private String desc;

    SexEnum(int value, String desc) {
   
        this.value = value;
        this.desc = desc;
    }

    @Override
    public Integer getValue() {
   
        return this.value;
    }

    @Override
    public String toString() {
   
        return this.desc;
    }
}

需要修改server与sso工程中的application.properties配置:

# 枚举包扫描
mybatis-plus.type-enums-package=com.tanhua.common.enums

将server与sso工程中的SexEnum对象删除以及将相关的类引用进行修改。

1.3、抽取mapper

需要将UserInfoMapper以及UserMapper放置到common工程的com.tanhua.common.mapper包下。

package com.tanhua.common.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tanhua.common.pojo.User;

public interface UserMapper extends BaseMapper<User> {
   

}
package com.tanhua.common.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.tanhua.common.pojo.UserInfo;

public interface UserInfoMapper extends BaseMapper<UserInfo> {
   

}

说明:抽取完成后,需要将原工程的代码删除以及修改其他代码中引入的依赖。

1.4、抽取pojo

将BasePojo、User、UserInfo移动至common工程:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AXRvr1ZC-1676812322017)(assets/image-20201208143929602

1.5、抽取utils

将server工程的utils进行抽取公用,后续的工具类也放置到common工程中。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HU0U9WH8-1676812322019)(assets/image-20201211113721758.png)]

抽取完成后进行测试,确保可以正常启动以及功能都正常。

2、圈子功能

2.1、功能说明

探花交友项目中的圈子功能,类似微信的朋友圈,基本的功能为:发布动态、浏览好友动态、浏览推荐动态、点赞、评论、喜欢等功能。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZmHhtuhe-1676812322019)(assets/1567496518185.png)]

发布:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-PwSUCDPQ-1676812322020)(assets/1567497614205.png)]

2.2、实现方案分析

对于圈子功能的实现,我们需要对它的功能特点做分析:

  • 数据量会随着用户数增大而增大
  • 读多写少,一般而言,浏览朋友圈动态会多一些,发动态相对就会少一些
  • 非好友看不到其动态内容
  • ……

针对以上特点,我们来分析一下:

  • 对于数据量大而言,显然不能够使用关系型数据库进行存储,我们需要通过MongoDB进行存储
  • 对于读多写少的应用,尽可能的减少读取数据的成本
    • 比如说,一条SQL语句,单张表查询一定比多张表查询要快
    • 条件越多的查询速度将越慢,尽可能的减少条件以提升查询速度

所以对于存储而言,主要是核心的4张表:

  • 发布表:记录了所有用户的发布的东西信息,如图片、视频等。
  • 相册:相册是每个用户独立的,记录了该用户所发布的所有内容。
  • 评论:针对某个具体发布的朋友评论和点赞操作。
  • 时间线:所谓“刷朋友圈”,就是刷时间线,就是一个用户所有的朋友的发布内容。

流程:

在这里插入图片描述

流程说明:

  • 用户发布动态,动态中一般包含了图片和文字,图片上传到阿里云,上传成功后拿到图片地址,将文字和图片地址进行持久化存储
  • 首先,需要将动态数据写入到发布表中,其次,再写入到自己的相册表中,需要注意的是,相册表中只包含了发布id,不会冗余存储发布数据
  • 最后,需要将发布数据异步的写入到好友的时间线表中,之所以考虑异步操作,是因为希望发布能够尽快给用户反馈,发布成功
  • 好友刷朋友圈时,实际上只需要查询自己的时间线表即可,这样最大限度的提升了查询速度,再配合redis的缓存,那速度将是飞快的
  • 用户在对动态内容进行点赞、喜欢、评论操作时,只需要写入到评论表即可,该表中也是只会记录发布id,并不会冗余存储发布数据

2.3、表结构设计

发布表:

#表名:quanzi_publish
{
   
    "_id":"5fae53d17e52992e78a3db61",#主键id
    "pid":1001, #发布id(Long类型)
    "userId":1, #用户id
    "text":"今天心情很好", #文本内容
    "medias":"http://xxxx/x/y/z.jpg", #媒体数据,图片或小视频 url
    "seeType":1, #谁可以看,1-公开,2-私密,3-部分可见,4-不给谁看
    "seeList":[1,2,3], #部分可见的列表
    "notSeeList":[4,5,6],#不给谁看的列表
	"longitude":108.840974298098,#经度
	"latitude":34.2789316522934,#纬度
    "locationName":"上海市浦东区", #位置名称
    "created",1568012791171 #发布时间
}

相册表:

#表名:quanzi_album_{
   userId}
{
   
    "_id":"5fae539d7e52992e78a3b684",#主键id
    "publishId":"5fae53d17e52992e78a3db61", #发布id
    "created":1568012791171 #发布时间
}

时间线表:

#表名:quanzi_time_line_{
   userId}
{
   
    "_id":"5fae539b7e52992e78a3b4ae",#主键id,
    "userId":2, #好友id
    "publishId":"5fae53d17e52992e78a3db61", #发布id
    "date":1568012791171 #发布时间
}

评论表:

#表名:quanzi_comment
{
   
    "_id":"5fae539d7e52992e78a3b648", #主键id
    "publishId":"5fae53d17e52992e78a3db61", #发布id
    "commentType":1, #评论类型,1-点赞,2-评论,3-喜欢
    "content":"给力!", #评论内容
    "userId":2, #评论人
    "publishUserId":9, #发布动态的人的id
    "isParent":false, #是否为父节点,默认是否
    "parentId":1001, #父节点id
    "created":1568012791171
}

3、好友关系数据

由于圈子中会涉及的好友关系数据,虽然现在主线是开发圈子功能,但是也需要对于好友关系有所了解,在我们提供的Mongodb数据库中有一些mock数据。

好友关系结构:

package com.tanhua.dubbo.server.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "tanhua_users")
public class Users implements java.io.Serializable{
   

    private static final long serialVersionUID = 6003135946820874230L;

    private ObjectId id;
    private Long userId; //用户id
    private Long friendId; //好友id
    private Long date; //时间

}

在mock数据中,为每个用户构造了10个好友数据:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GqCRKOpg-1676812322021)(assets/image-20201208212007691.png)]

4、查询好友动态

查询好友动态与查询推荐动态显示的结构是一样的,只是其查询数据源不同:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-agy7aN2u-1676812322022)(assets/1567496518185.png)]

4.1、基础代码

在my-tanhua-dubbo-interface中编写:

package com.tanhua.dubbo.server.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;
import java.util.List;

/**
 * 发布表,动态内容
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_publish")
public class Publish implements java.io.Serializable {
   

    private static final long serialVersionUID = 8732308321082804771L;

    @Id
    private ObjectId id; //主键id
    private Long pid; //发布id
    private Long userId; //发布用户id
    private String text; //文字
    private List<String> medias; //媒体数据,图片或小视频 url
    private Integer seeType; // 谁可以看,1-公开,2-私密,3-部分可见,4-不给谁看
    private List<Long> seeList; //部分可见的列表
    private List<Long> notSeeList; //不给谁看的列表
    private String longitude; //经度
    private String latitude; //纬度
    private String locationName; //位置名称
    private Long created; //发布时间

}
package com.tanhua.dubbo.server.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

/**
 * 相册表,用于存储自己发布的数据,每一个用户一张表进行存储
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_album_{userId}")
public class Album implements java.io.Serializable {
   

    private static final long serialVersionUID = 432183095092216817L;

    @Id
    private ObjectId id; //主键id

    private ObjectId publishId; //发布id
    private Long created; //发布时间

}
package com.tanhua.dubbo.server.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

/**
 * 时间线表,用于存储发布的数据,每一个用户一张表进行存储
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_time_line_{userId}")
public class TimeLine implements java.io.Serializable {
   
    private static final long serialVersionUID = 9096178416317502524L;
    
    @Id
    private ObjectId id;
    private Long userId; // 好友id
    private ObjectId publishId; //发布id
    private Long date; //发布的时间

}

package com.tanhua.dubbo.server.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.bson.types.ObjectId;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

import java.util.Date;

/**
 * 评论表
 */
@Data
@NoArgsConstructor
@AllArgsConstructor
@Document(collection = "quanzi_comment")
public class Comment implements java.io.Serializable{
   

    private static final long serialVersionUID = -291788258125767614L;

    @Id
    private ObjectId id;
    private ObjectId publishId; //发布id
    private Integer commentType; //评论类型,1-点赞,2-评论,3-喜欢
    private String content; //评论内容
    private Long userId; //评论人
    private Long publishUserId; //发布动态的用户id
    private Boolean isParent = false; //是否为父节点,默认是否
    private ObjectId parentId; // 父节点id
    private Long created; //发表时间

}

4.2、dubbo服务

圈子的具体业务逻辑的实现需要在dubbo中完成,所以需要开发dubbo服务。

4.2.1、定义接口

在my-tanhua-dubbo-interface工程中:

package 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值