Mongodb | 基于Springboot开发综合社交网络应用的项目案例(中英)
目录
Project background
Development time
Project questions
Create Project
create springboot project
project framework
create folder
Create Models
user
post
Comment
Like
Message
Serive tier
user login and register
Dynamic Publishing and Browsing
Comment likes
message notification
Page-based query implementation
关联查询实现
用户和动态关联
动态和评论关联
部署与扩展
Project background
Function description: Achieve functions such as user social relationship management, dynamic posting and browsing, comment and like functions, and message notification.
功能描述 :实现用户的社交关系管理、动态发布与浏览、评论点赞、消息通知等功能。
Handling the association relationships of documents: The user's basic information, social relationships, published content, comments, etc. can be stored in different document collections. Then, through the references or nested structures within the documents, association relationships can be established, facilitating data querying and operations. For example, when querying a user's friend's dynamic, the content published by the friend can be obtained through an association query.
Efficient data pagination and querying: For scenarios such as users browsing dynamic posts and message lists, MongoDB provides efficient data pagination query functions, which can quickly return data within a specified range and improve user experience.
Flexible scalability: As the number of users and data volume increase, MongoDB's storage cluster can be easily expanded to meet the expansion requirements of the application.
文档的关联关系处理 :可以将用户的基本信息、社交关系、发布的内容、评论等存储在不同的文档集合中,然后通过文档中的引用或嵌套结构来建立关联关系,方便进行数据的查询和操作,例如查询一个用户的好友动态时,可以通过关联查询获取好友发布的内容。 高效的数据分页与查询 :对于用户浏览动态、消息列表等场景,MongoDB 提供了高效的数据分页查询功能,能够快速返回指定范围内的数据,提高用户体验。 灵活的扩展性 :随着用户数量和数据量的增长,可以方便地扩展 MongoDB 的存储集群,满足应用的扩展需求。
Development time
Start time : May 27,2025 23:00
End Time : now
Project questions
- null
Create Project
create springboot project
project framework
social-network-app/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ ├── com.example.socialnetwork/
│ │ │ │ ├── SocialNetworkApplication.java
│ │ │ │ ├── config/
│ │ │ │ │ └── MongoConfig.java
│ │ │ │ ├── controller/
│ │ │ │ │ ├── UserController.java
│ │ │ │ │ ├── PostController.java
│ │ │ │ │ ├── CommentController.java
│ │ │ │ │ ├── LikeController.java
│ │ │ │ │ └── MessageController.java
│ │ │ │ ├── model/
│ │ │ │ │ ├── User.java
│ │ │ │ │ ├── Post.java
│ │ │ │ │ ├── Comment.java
│ │ │ │ │ ├── Like.java
│ │ │ │ │ └── Message.java
│ │ │ │ ├── repository/
│ │ │ │ │ ├── UserRepository.java
│ │ │ │ │ ├── PostRepository.java
│ │ │ │ │ ├── CommentRepository.java
│ │ │ │ │ ├── LikeRepository.java
│ │ │ │ │ └── MessageRepository.java
│ │ │ │ ├── service/
│ │ │ │ │ ├── UserService.java
│ │ │ │ │ ├── PostService.java
│ │ │ │ │ ├── CommentService.java
│ │ │ │ │ ├── LikeService.java
│ │ │ │ │ └── MessageService.java
│ │ │ │ └── dto/
│ │ │ │ ├── UserDto.java
│ │ │ │ ├── PostDto.java
│ │ │ │ ├── CommentDto.java
│ │ │ │ ├── LikeDto.java
│ │ │ │ └── MessageDto.java
│ │ └── resources/
│ │ ├── application.properties
│ │ └── static/
│ └── test/
└── pom.xml
create folder
Create Models
user
package com.socialnetwork.www.model;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.ArrayList;
import java.util.List;@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(collection = "users")
public class User {@Idprivate String id;private String username;private String password;private String email;private String profilePicture;private String bio;private List<String> followers = new ArrayList<>();private List<String> following = new ArrayList<>();
}
post
package com.socialnetwork.www.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import javax.xml.stream.events.Comment;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(collection = "posts")
public class Post {@Idprivate String id;private String userId;private String content;private List<String> images;private Date createdAt;private int likeCount = 0;private List<Comment> comments = new ArrayList<>();
}
Comment
package com.socialnetwork.www.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(collection = "comments")
public class Comments {@Idprivate String id;private String userId;private String postId;private String content;private Date createdAt;private int likeCount = 0;
}
Like
package com.socialnetwork.www.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(collection = "likes")
public class Like {@Idprivate String id;private String userId;private String postId;private String commentId;private Date createdAt;// Getters and Setters
}
Message
package com.socialnetwork.www.model;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;import java.util.Date;@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
@Document(collection = "messages")
public class Message {@Idprivate String id;private String senderId;private String receiverId;private String content;private Date sentAt;private boolean read = false;
}
Serive tier
user login and register
用户 登录和注册
@RestController
@RequestMapping("/api/users")
public class UserController {@Autowiredprivate UserService userService;@PostMapping("/register")public ResponseEntity<?> registerUser(@RequestBody UserDto userDto) {User user = userService.registerUser(userDto);return ResponseEntity.ok(user);}@PostMapping("/login")public ResponseEntity<?> loginUser(@RequestBody UserDto userDto) {User user = userService.loginUser(userDto);return ResponseEntity.ok(user);}
}
@Service
public class UserService {@Autowiredprivate UserRepository userRepository;public User registerUser(UserDto userDto) {User user = new User();user.setUsername(userDto.getUsername());user.setPassword(bCryptPasswordEncoder.encode(userDto.getPassword()));user.setEmail(userDto.getEmail());return userRepository.save(user);}public User loginUser(UserDto userDto) {User user = userRepository.findByUsername(userDto.getUsername());if (user != null && bCryptPasswordEncoder.matches(userDto.getPassword(), user.getPassword())) {return user;}return null;}
}
Dynamic Publishing and Browsing
动态发布与浏览
@RestController
@RequestMapping("/api/posts")
public class PostController {@Autowiredprivate PostService postService;@PostMappingpublic ResponseEntity<?> createPost(@RequestBody PostDto postDto, @AuthenticationPrincipal String userId) {Post post = postService.createPost(postDto, userId);return ResponseEntity.ok(post);}@GetMappingpublic ResponseEntity<?> getPosts(@RequestParam int page, @RequestParam int size) {Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));Page<Post> posts = postService.getPosts(pageable);return ResponseEntity.ok(posts);}
}
@Service
public class PostService {@Autowiredprivate PostRepository postRepository;public Post createPost(PostDto postDto, String userId) {Post post = new Post();post.setUserId(userId);post.setContent(postDto.getContent());post.setImages(postDto.getImages());post.setCreatedAt(new Date());return postRepository.save(post);}public Page<Post> getPosts(Pageable pageable) {return postRepository.findAll(pageable);}
}
Comment likes
评论点赞
@RestController
@RequestMapping("/api/comments")
public class CommentController {@Autowiredprivate CommentService commentService;@PostMappingpublic ResponseEntity<?> addComment(@RequestBody CommentDto commentDto, @AuthenticationPrincipal String userId) {Comment comment = commentService.addComment(commentDto, userId);return ResponseEntity.ok(comment);}@PostMapping("/{commentId}/like")public ResponseEntity<?> likeComment(@PathVariable String commentId, @AuthenticationPrincipal String userId) {Like like = commentService.likeComment(commentId, userId);return ResponseEntity.ok(like);}
}
@Service
public class CommentService {@Autowiredprivate CommentRepository commentRepository;@Autowiredprivate LikeRepository likeRepository;public Comment addComment(CommentDto commentDto, String userId) {Comment comment = new Comment();comment.setUserId(userId);comment.setPostId(commentDto.getPostId());comment.setContent(commentDto.getContent());comment.setCreatedAt(new Date());return commentRepository.save(comment);}public Like likeComment(String commentId, String userId) {Like like = new Like();like.setUserId(userId);like.setCommentId(commentId);like.setCreatedAt(new Date());return likeRepository.save(like);}
}
message notification
消息通知
@RestController
@RequestMapping("/api/messages")
public class MessageController {@Autowiredprivate MessageService messageService;@PostMappingpublic ResponseEntity<?> sendMessage(@RequestBody MessageDto messageDto, @AuthenticationPrincipal String userId) {Message message = messageService.sendMessage(messageDto, userId);return ResponseEntity.ok(message);}@GetMappingpublic ResponseEntity<?> getMessages(@RequestParam String receiverId, @RequestParam int page, @RequestParam int size) {Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "sentAt"));Page<Message> messages = messageService.getMessages(receiverId, pageable);return ResponseEntity.ok(messages);}
}
@Service
public class MessageService {@Autowiredprivate MessageRepository messageRepository;public Message sendMessage(MessageDto messageDto, String userId) {Message message = new Message();message.setSenderId(userId);message.setReceiverId(messageDto.getReceiverId());message.setContent(messageDto.getContent());message.setSentAt(new Date());message.setRead(false);return messageRepository.save(message);}public Page<Message> getMessages(String receiverId, Pageable pageable) {return messageRepository.findByReceiverId(receiverId, pageable);}
}
Page-based query implementation
分页查询实现
在 Spring Data MongoDB 中,可以使用 Pageable
接口来实现分页查询。
public interface PostRepository extends MongoRepository<Post, String> {Page<Post> findAll(Pageable pageable);
}
在控制器中使用:
@GetMapping
public ResponseEntity<?> getPosts(@RequestParam int page, @RequestParam int size) {Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));Page<Post> posts = postService.getPosts(pageable);return ResponseEntity.ok(posts);
}
关联查询实现
使用 MongoDB 的 @DBRef
注解可以实现文档之间的关联查询。
用户和动态关联
在 Post
文档中,userId
字段关联到 User
文档。
@Document(collection = "posts")
public class Post {@Idprivate String id;private String userId;private String content;private List<String> images;private Date createdAt;private int likeCount = 0;private List<Comment> comments = new ArrayList<>();// Getters and Setters
}
在控制器中,可以通过 userId
查询用户信息:
@GetMapping("/{postId}")
public ResponseEntity<?> getPost(@PathVariable String postId) {Post post = postService.getPost(postId);User user = userService.getUser(post.getUserId());return ResponseEntity.ok(post);
}
动态和评论关联
在 Comment
文档中,postId
字段关联到 Post
文档。
@Document(collection = "comments")
public class Comment {@Idprivate String id;private String userId;private String postId;private String content;private Date createdAt;private int likeCount = 0;// Getters and Setters
}
在控制器中,可以通过 postId
查询评论列表:
@GetMapping("/{postId}/comments")
public ResponseEntity<?> getComments(@PathVariable String postId) {List<Comment> comments = commentService.getComments(postId);return ResponseEntity.ok(comments);
}
部署与扩展
在生产环境中,可以使用 MongoDB 的分片功能来支持大规模数据的存储和查询。
spring.data.mongodb.uri=mongodb://username:password@host1:port1,host2:port2,host3:port3/database?replicaSet=replicaSetName
- Thanks you -
相关文章:

Mongodb | 基于Springboot开发综合社交网络应用的项目案例(中英)
目录 Project background Development time Project questions Create Project create springboot project project framework create folder Create Models user post Comment Like Message Serive tier user login and register Dynamic Publishing and Bro…...

飞腾D2000与FPGA结合的主板
UD VPX-404是基于高速模拟/数字采集回放、FPGA信号实时处理、CPU主控、高速SSD实时存储架构开发的一款高度集成的信号处理组合模块,采用6U VPX架构,模块装上外壳即为独立整机,方便用户二次开发。 UD VPX-404模块的国产率可达到100%࿰…...

百度量子蜘蛛3.0横空出世,搜索引擎迎来“量子跃迁“级革命
一、量子蜘蛛3.0的三大颠覆性升级 1. 动态抓取:让内容实时"量子纠缠" - 智能频率调节:根据网站更新频率自动调整抓取节奏,新闻类站点日抓取量达3-5次,静态页面抓取间隔延长至72小时。某财经媒体通过"热点事件15分钟…...

GitHub开源|AI顶会论文中文翻译PDF合集(gpt-translated-pdf-zh)
项目核心特点 该项目专注于提供计算机科学与人工智能领域的高质量中文翻译资源,以下为关键特性: 主题覆盖广泛:包含算法、数据结构、概率统计等基础内容,以及深度学习、强化学习等前沿研究方向。格式统一便捷:所有文…...
JSR 303(即 Bean Validation)是一个通过注解在 Java Bean 上定义和执行验证规则的规范
🛠️ 一、JSR 303是什么? JSR 303(Java Specification Requests 303)是Java EE 6的子规范,全称Bean Validation。它通过注解方式对JavaBean的属性值进行标准化校验,例如检查非空、长度、格式等规则…...
5G 网络中的双向认证机制解析
一、5G 网络中的双向认证机制解析 在 5G 核心网中,双向认证是指UE(用户设备)与网络互相验证对方身份的过程。这一机制通过多层次的安全协议和密钥交换,确保通信双方的合法性,防止中间人攻击和身份伪造。 1. UE 存储的关键信息 UE 作为用户终端,存储以下核心安全信息:…...
DAY07:Vue Router深度解析与多页面博客系统实战
第一部分:Vue Router核心概念深度剖析 1.1 现代前端路由的本质 在单页应用(SPA)时代,前端路由扮演着至关重要的角色。它突破了传统多页面应用的跳转方式,通过以下机制实现无刷新页面切换: Hash模式&#…...

Drawio编辑器二次开发
Drawio (现更名为 Diagrams.net )是一款完全免费的在线图表绘制工具,由 JGraph公司 开发。它支持创建多种类型的图表,包括流程图、组织结构图、UML图、网络拓扑图、思维导图等,适用于商务演示、软件设计等多种场景…...

1.测试过程之需求分析和测试计划
测试基础 流程 1.分析测试需求 2.编写测试计划 3.设计与编写测试用例 4.执行测试 5.评估与总结 测试目标 根据测试阶段不同可分为四个主要目标:预防错误(早期)、发现错误(开发阶段)、建立信心(验收阶段&a…...
第三十七天打卡
过拟合的判断:测试集和训练集同步打印指标模型的保存和加载 仅保存权重保存权重和模型保存全部信息checkpoint,还包含训练状态 早停策略 过拟合判断 import torch import torch.nn as nn import torch.optim as optim from sklearn.datasets import load…...
Qt 窗口标志(Window Flags)详解:控制窗口样式与行为
在 Qt 中,windowFlags 用于控制窗口的样式和行为,包括标题栏、边框、最大化/最小化按钮等。合理设置 windowFlags 可以自定义窗口的外观和交互方式。本文将详细介绍常用的窗口标志及其组合效果。 1. 基本概念 windowFlags 是一个 Qt::WindowFlags 类型的…...
ABP VNext + CRDT 打造实时协同编辑
🛠️ ABP VNext CRDT 打造实时协同编辑器 🎉 📚 目录 🛠️ ABP VNext CRDT 打造实时协同编辑器 🎉🧠 背景与挑战🔹 系统架构🛣️ 端到端流程 🚦🔒 安全与鉴…...
微信小程序真机调试时如何实现与本地开发环境服务器交互
最近在开发微信小程序项目,真机调试时需要在手机上运行小程序,为了实现本地开发服务器与手机小程序的交互,需要以下步骤 1.将手机连到和本地一样的局域网 2.Visual Studio中将IIS Express服务器的localhost端口地址修改为本机的IP自定义的端口: 1)找到web api项目…...
Linux: network: dpdk, VF, ip link set down 对VF不生效
文章目录 问题另一个测试的结果是从dpdk的文档看怎么设置VF给VM内核的调用需要使用的命令问题 最近遇到一个问题,也可以说是一种常识,至少是之前不知道的常识:如果一个VF分配给了VM用作dpdk的输入。在host做ip link set down 这个PF的接口,对这个VM里的VF的功能没有任何影…...

[春秋云镜] CVE-2023-23752 writeup
首先奉上大佬的wp表示尊敬:(很详细)[ 漏洞复现篇 ] Joomla未授权访问Rest API漏洞(CVE-2023-23752)_joomla未授权访问漏洞(cve-2023-23752)-CSDN博客 知识点 Joomla版本为4.0.0 到 4.2.7 存在未授权访问漏洞 Joomla是一套全球知名的内容管理…...
Java集合操作常见错误与最佳实践
错误69:搜索无关类型的对象 泛型方法的类型安全漏洞 在Java引入参数化类型前,集合元素只能声明为Object类型,导致可以随意将字符串添加到数值列表中。虽然泛型机制对添加元素的方法进行了类型约束,但搜索和删除相关方法仍保留了Object类型的参数设计。这包括以下关键方法…...

CSS专题之水平垂直居中
前言 石匠敲击石头的第 16 次 在日常开发中,经常会遇到水平垂直居中的布局,虽然现在基本上都用 Flex 可以轻松实现,但是在某些无法使用 Flex 的情况下,又应该如何让元素水平垂直居中呢?这也是一道面试的必考题…...
python打卡day41@浙大疏锦行
知识回顾 1. 数据增强 2. 卷积神经网络定义的写法 3. batch归一化:调整一个批次的分布,常用与图像数据 4. 特征图:只有卷积操作输出的才叫特征图 5. 调度器:直接修改基础学习率 卷积操作常见流程如下: 1. …...
vue3 基本语法 父子关系
在Vue 3中,父子组件的关系是通过组件的嵌套实现的。父组件可以传递数据(props)给子组件,同时子组件可以通过事件(emits)与父组件通信。下面是如何在Vue 3中建立和使用父子组件的基本语法: 1. 创…...
算法-js-子集
题:给你一个整数数组 nums ,数组中的元素 互不相同 。返回该数组所有可能的子集(幂集)。解集 不能 包含重复的子集。你可以按 任意顺序 返回解集。 方法一:迭代法 核心逻辑:动态扩展子集, 小规…...

(新)MQ高级-MQ的可靠性
消息到达MQ以后,如果MQ不能及时保存,也会导致消息丢失,所以MQ的可靠性也非常重要。 一、数据持久化 为了提升性能,默认情况下MQ的数据都是在内存存储的临时数据,重启后就会消失。为了保证数据的可靠性,必须…...
Android设置界面层级为最上层实现
Android设置界面层级为最上层实现 文章目录 Android设置界面层级为最上层实现一、前言二、Android设置界面层级为最上层实现1、主要代码2、后遗症 三、其他1、Android设置界面层级为最上层小结2、悬浮框的主要代码悬浮框 注意事项(1)权限限制(…...
云原生微服务架构演进之路:理念、挑战与实践
📝个人主页🌹:慌ZHANG-CSDN博客 🌹🌹期待您的关注 🌹🌹 一、引言:架构的演进是业务进化的技术反射 在软件行业的发展过程中,架构变迁总是伴随着技术浪潮与业务复杂度的升…...
Go语言使用阿里云模版短信服务
在当今的互联网项目中,短信验证码、通知等功能已成为标配。本文将详细介绍如何使用Go语言集成阿里云短信服务(DYSMSAPI)实现短信发送功能。 一、准备工作 在开始之前,您需要完成以下准备工作: 注册阿里云账号并实名认证开通短信服务(SMS)申…...

Leetcode 3231. 要删除的递增子序列的最小数量
1.题目基本信息 1.1.题目描述 给定一个整数数组 nums,你可以执行任意次下面的操作: 从数组删除一个 严格递增 的 子序列。 您的任务是找到使数组为 空 所需的 最小 操作数。 1.2.题目地址 https://leetcode.cn/problems/minimum-number-of-increas…...

4.2.5 Spark SQL 分区自动推断
在本节实战中,我们学习了Spark SQL的分区自动推断功能,这是一种提升查询性能的有效手段。通过创建具有不同分区的目录结构,并在这些目录中放置JSON文件,我们模拟了一个分区表的环境。使用Spark SQL读取这些数据时,Spar…...
基于昇腾MindSpeed训练加速库玩转智谱GLM-4-0414模型
智谱GLM-4-0414模型提供32B和9B两种参数规模,涵盖基础、推理和沉思等多种模型类型,均基于 MIT 许可协议开放。其中,推理模型 GLM-Z1-32B-0414 性能卓越,与 DeepSeek-R1 等领先模型相当,实测推理速度达每秒200个Tokens。…...

【图像处理入门】2. Python中OpenCV与Matplotlib的图像操作指南
一、环境准备 import cv2 import numpy as np import matplotlib.pyplot as plt# 配置中文字体显示(可选) plt.rcParams[font.sans-serif] [SimHei] plt.rcParams[axes.unicode_minus] False二、图像的基本操作 1. 图像读取、显示与保存 使用OpenCV…...

Spring Boot微服务架构(九):设计哲学是什么?
一、Spring Boot设计哲学是什么? Spring Boot 的设计哲学可以概括为 “约定优于配置” 和 “开箱即用”,其核心目标是极大地简化基于 Spring 框架的生产级应用的初始搭建和开发过程,让开发者能够快速启动并运行项目…...
GRCh38版本染色体位置转换GRCh37(hg19)
目录 方法 1:使用 Ensembl REST API(推荐,适用于少量位点查询)方法 2:使用 UCSC API方法 3:使用 NCBI API 并转换坐标(需要额外步骤)方法 4:使用本地数据库(最…...