☰
Java 项目实战: 交友项目 - 通用设置、黑名单与 MongoDB 入门
2026/10/21 2:32:12 网站建设 项目流程

概述

昨天用户已经"资料完整",但产品还缺一块控制面板:谁能给我发消息、通知要不要推送、看谁不顺眼能不能屏蔽。今天补上这块"隐私与打扰的边界控制",同时引入一个全新的存储引擎 MongoDB——它不只是给今天的功能用,更是为后面的圈子动态铺路。

纲要

  • 衔接:之前的产出如何被现在直接复用
  • 昨日回顾:OSS、人脸识别、资料 CRUD、拦截器鉴权、统一异常(只列清单)
  • 今日任务书:五个板块的做什么 / 产出物 / 验收标准
    • 通用设置(查询 + 保存通知开关)
    • 陌生人问题(一用户一条的保存与更新)
    • 通知设置(幂等落库)
    • 黑名单(分页查询 + 取消拉黑)
    • MongoDB 入门(安装、体系结构、shell CRUD、索引、SpringData-Mongo)
  • 依赖关系图与工程产出预告
  • 学习建议与常见误解澄清

从昨天到今天:产品视角的衔接

之前结束时,用户能完善资料、上传头像、查看和修改个人信息。但从产品角度看,用户的"自主权"还是零:平台推什么就看什么,谁都能来搭讪,通知发不发也只能全盘接收。

今天做的通用设置模块就是解决这件事。按讲义的定义,它包含三块:

  • 设置陌生人问题:其他用户想在线交流时,必须先回答这个问题,相当于一道门槛;
  • 通知设置:喜欢、评论、公告三类推送的开关;
  • 黑名单:对不感兴趣的用户屏蔽骚扰。

存储层面有个容易忽略的细节:这三块今天全部落在 MySQL(tb_settings、tb_question、tb_black_list三张表),而今天引入的 MongoDB 暂时不给它们用——它服务于"今日佳人"这个功能(推荐好友列表是大数据系统算好存进 Mongo 的,今天只是第一次用 Java 去读),真正的重头戏在后面的圈子动态。

还要交代一个边界:讲义里黑名单部分只包含分页查询和移除黑名单两个接口。"把人拉进黑名单"这个动作本身挂在后续的互动功能里(比如对某条动态操作时触发),今天先把名单的管理能力建好。

回顾:之前做了什么

只列清单,细节各有专篇,这里不展开:

板块做了什么产出物可复用套路
阿里云 OSS头像上传到对象存储,抽取成自动装配组件OssTemplate第三方 SDK 封装成 template + starter
百度人脸识别上传头像前做人脸检测校验AipFaceTemplate同上,模板工具类 + 配置属性类
用户资料 CRUD保存、查询、更新tb_user_infoUserInfoApi+UserInfoVoController → Service → Dubbo API → Mapper
统一 token 处理拦截器校验 JWT,ThreadLocal存当前用户TokenInterceptor+UserHolder任何接口里一行UserHolder.getUserId()拿人
统一异常处理业务异常集中兜底BusinessException+ExceptionAdvice+ErrorResultService 抛异常,Controller 不用写 try-catch

今天写的每一个接口,鉴权和异常兜底都是白捡的——拦截器放行后直接取用户 ID,出问题直接抛BusinessException。

今日任务书

本篇的核心。五个板块,每个都有可验证的验收标准:

板块做什么产出物验收标准
① 通用设置查询设置项 + 保存三类通知开关GET /users/settings、SettingsController、SettingsVo、tb_settings新用户首次查询返回默认值(三个开关均为开);保存后刷新页面不丢
② 陌生人问题保存/更新问题内容POST /users/questions、QuestionApi、tb_question保存后能查回;同一用户重复保存不产生重复行(有则更新、无则插入)
③ 通知设置单独保存通知开关POST /users/notifications/setting开关正确落库;重复提交结果一致(幂等),不报错、不产生脏数据
④ 黑名单管理分页查询黑名单 + 取消拉黑GET /users/blacklist、DELETE /users/blacklist/{uid}、BlackListApi、PageResult分页数据正确且带对方资料(关联tb_user_info);取消后该用户从列表消失
⑤ MongoDB 入门认识文档数据库 → Docker 安装 → 体系结构与数据类型 → shell 增删改查 → 索引与执行计划 → SpringBoot 整合单机 MongoDB 环境 +mf-dubbo-mongo模块能连上库并完成基本 CRUD;Java 端用 SpringData-Mongo 存取文档成功

②③ 有个共同的设计点提前说:SettingsService里的保存逻辑都是"先按userId查,查到就update,查不到就save"。这样新用户第一次保存也不会因为没有记录而报错,这就是设置类功能最典型的"默认值 + 幂等"处理。

⑤ 按讲义的实际编排,覆盖 MongoDB 简介、Docker 安装、体系结构、数据类型、入门 CRUD、索引、执行计划,以及 SpringData-Mongo 整合;讲义最后用"今日佳人"功能做了首个实战——推荐好友数据存在 Mongo 的recommend_user集合里,工程上新增了mf-dubbo-mongo这个独立 Dubbo 服务模块来读它。这块在下面的产出预告里能看到对应代码。

依赖关系

现在 新增

之前已有地基

拦截器 + ThreadLocal 鉴权

统一异常处理

Dubbo 分层架构
app-server / dubbo-interface / dubbo-db

通用设置 SettingsApi

陌生人问题 QuestionApi

黑名单 BlackListApi

mf-dubbo-mongo 模块

MySQL
tb_settings / tb_question / tb_black_list

MongoDB
recommend_user

后续规划:圈子动态 / 即时通信

一句话概括:设置与黑名单是"旧地基上的新房间",直接复用 day02 的鉴权、异常和分层套路;MongoDB 是"新地基",今天打地基,后面圈子功能的高楼盖在它上面。

接口速览

方法路径作用
GET/users/settings查询通用设置(陌生人问题 + 三类通知开关)
POST/users/questions保存/更新陌生人问题
POST/users/notifications/setting保存通知开关
GET/users/blacklist?page=&pagesize=分页查询黑名单列表
DELETE/users/blacklist/{uid}取消黑名单

工程产出预告

对照 之前 的代码快照,今天结束时工程里会多出这些类(以之前代码实读为准):

mf ├── mf-app-server │ └── src/main/java/com/mf/server │ ├── controller/SettingsController.java # 设置面板唯一入口,挂 5 个接口 │ ├── controller/mfController.java # 今日佳人接口(MongoDB 首个实战) │ ├── service/SettingsService.java # 设置/问题/通知/黑名单的业务逻辑 │ └── service/mfService.java # 今日佳人业务逻辑 ├── mf-dubbo │ ├── mf-dubbo-interface │ │ └── com/mf/dubbo/api │ │ ├── SettingsApi.java # 设置项的按 userId 查/存/改 │ │ ├── QuestionApi.java # 陌生人问题的查/存/改 │ │ ├── BlackListApi.java # 分页查黑名单、移除 │ │ └── RecommendUserApi.java # Mongo 侧推荐用户查询接口定义 │ ├── mf-dubbo-db │ │ └── com/mf/dubbo │ │ ├── api/SettingsApiImpl.java # 操作 tb_settings │ │ ├── api/QuestionApiImpl.java # 操作 tb_question │ │ ├── api/BlackListApiImpl.java # 操作 tb_black_list,分页返回 UserInfo │ │ └── mappers/SettingsMapper.java 等 # 三张新表对应的 Mapper │ └── mf-dubbo-mongo # 新模块:独立的 Mongo Dubbo 服务 │ ├── DubboMongoApplication.java # 独立启动类 │ └── api/RecommendUserApiImpl.java # 用 SpringData-Mongo 读 recommend_user └── mf-model └── src/main/java/com/mf/model ├── domain/Settings.java # 通知设置实体,三个 Boolean 开关 ├── domain/Question.java # 陌生人问题实体(userId + txt) ├── domain/BlackList.java # 黑名单实体(userId + blackUserId) ├── mongo/RecommendUser.java # Mongo 文档实体,@Document 注解 └── vo/SettingsVo.java、PageResult.java、TodayBest.java # 返回值对象

注意mf-dubbo-mongo是个独立模块、独立进程——MySQL 的 API 和 Mongo 的 API 分属两个 Dubbo 服务,存储引擎不同就连部署单元也分开,这个分层决定后面会一直沿用。

学习建议

  • 设置类功能小而多,套路雷同,重点不是写出多少接口,而是吃透默认值与幂等:新用户没有记录时查询给默认值、保存走"有则更新无则插入",这两招以后做任何用户偏好类功能都用得上。
  • 黑名单重点学分页查询 + 关联查询:BlackListApiImpl里要拿着黑名单的blackUserId列表去tb_user_info捞资料,这个"先查 ID 再补详情"的模式很常见。
  • MongoDB 是全新的概念体系(集合、文档、BSON、_id),先照着讲义把环境跑起来、CRUD 敲一遍,体系结构的细节用到再回头深究,别卡在概念上。
  • 遇到报错先看 Dubbo 服务有没有起全——今天多了一个mf-dubbo-mongo进程,忘了启动就是NoSuchProviderException这类找不到提供者的错。

常见误解澄清

误解实际情况
“设置就是几个开关的小功能”设置是产品的隐私与打扰边界:陌生人问题是社交门槛,通知开关决定打扰策略,做错了直接影响用户体验和数据一致性
“黑名单只是一个列表”黑名单会在推荐、互动等多个环节被过滤使用;今天的接口只是管理名单本身,真正的拦截发生在后续功能里
“MongoDB 就是另一个 MySQL”MongoDB 是文档模型:没有表和行的概念,是集合和 BSON 文档,无 schema、_id自动生成,查询语法是完全另一套
“设置类接口不用考虑并发”用户双击保存、断网重试都会造成重复提交,"有则更新无则插入"加幂等设计就是为此准备的
“新模块可以塞进现有工程里省事”Mongo 服务独立成mf-dubbo-mongo是刻意的:引擎不同、依赖不同、后续扩容节奏也不同,拆开才能各自演进

从哪篇开始

目前实质内容《通用设置:需求分析》已经就位,直接从它开始——先看三张表怎么设计、为什么实体类都继承BasePojo,然后按 1.2 → 1.5 的顺序把五个接口依次写完,最后进入 MongoDB 部分。

总结

  • 之前 解决"资料完整",现在解决"边界可控":设置、陌生人问题、通知、黑名单四块合成用户的控制面板。
  • 今天的功能全部复用 之前 的鉴权、异常与 Dubbo 分层,增量只有三张表、五个接口和一套"默认值 + 幂等"的处理方式。
  • MongoDB 今天完成环境搭建与入门,实战落点是今日佳人;圈子动态才是它的主场。
  • 验收标准逐条过:新用户查设置有默认值、保存后不丢、重复提交幂等、黑名单分页正确且可取消、Mongo 能连能存取。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询