前置知识

1. 软件的生命周期

生命周期: 对事物进行定义(描述) -> 创建 -> 使用 -> 销毁的过程

软件⽣命周期中以划分为可⾏性研究、需求分析、概要设计、详细设计、实现、组装(集成)测试、确认测试、使⽤、维护、退役10个阶段,如下图:

a. 可⾏性研究:通过分析软件开发要求,确定软件项⽬的性质、⽬标和规模,得出可⾏性研究报告,如果可⾏性研究报告是可⾏的,就要制订详细的项⽬开发计划。此阶段交付成果为可⾏性研究报告(可行性研究报告: 经济可行性(资金够不够), 技术可行性(市面上的技术能否满足这个需求);

b. 需求分析:是软件⽣命周期中重要的也是决定性的⼀步,通过需求分析才能把软件功能和性能的总体概念描述为具体的软件需求规格说明书,为软件开发奠定基础,此阶段交付成果为软件需求规格说明书(需求文档: 用于直到设计, 开发,测试,交付,运维....)

c. 概要设计:根据软件需求规格说明建⽴软件系统的总体结构和模块间的关系定义各功能模块接⼝,设计全局数据库或数据结构,规定设计约束,制定组装(集成)测试计划;

d. 详细设计:将各模块要实现的功能⽤相应的设计⼯具详细的描述出来。(具体的数据流程都要描述清楚,指导开发工作)

e. 实现:写出正确的、易理解的和易维护的程序模块。程序员根据详细设计⽂档将详细设计转化为程序,完成单元测试;(编码阶段)

f. 组装测试(集成测试):将经过单元测试的模块逐步进⾏组装和测试;

g. 确认测试:测试系统是否达到了系统要求,按照规格说明书的规定,由⽤⼾(或在⽤⼾积极参与

下)对系统进⾏验收。必要时,还可以再通过现场测试或并⾏运⾏等⽅法对系统进⾏进⼀步测试;

h. 使⽤:将软件安装在⽤⼾确定的运⾏环境中,测试通过后移交⽤⼾使⽤。在软件使⽤过程中,客⼾和维护⼈员必须认真收集发现的软件错误,定期或阶段性的撰写软件问题报告和软件修改报告;

i. 维护:通过各种必要的维护活动使系统持久的满⾜⽤⼾需要;

j. 退役:终⽌对软件产品的⽀持,软件停⽌使⽤。

一个例子: 关于想吃西红柿炒鸡蛋

西红柿炒鸡蛋软件⽣命周期
想吃且⾃⼰会做需求产⽣,可以实现
确定⼝味,分量,其他配菜需求分析,确定功能,规模
按⼝味轻重确定调料多少,按分量确定菜准备多少设计阶段
开炒开发阶段
尝⼀下⼝味是否合适,淡了加盐,咸了加西红柿测试阶段
端上桌,开吃部署、使⽤阶段
吃完洗碗退役

后续我们对对下面几个阶段进行展开: 主要完成需求分析、概要及详细(系统)设计、实现、单元和集成测试、部署使⽤这⼏个阶段的任务。

 2. 面向对象

面向过程: 以正在发生的事情为主要目标进行编程

面向对象: 关注的是谁被影响, 使用时调用对象相关的方法

具体面向对象的解释

• ⼀种软件开发的⽅法,是相对于⾯向过程来说的。

• 以对象为中⼼,把相关的数据和⽅法组织为⼀个整体并抽象成类,从⽽更贴近事物的⾃然运⾏模

式。

• 在⾯向对象程序设计中,对象中应该包含数据和动作

• 在⾯向对象编程中,其中对象的数据对应表⽰为属性,对象的动作表⽰为⽅法

使⽤⾯向对象⽅法对系统进⾏构建主要分为以下⼏个阶段:

1> 面向对象分析(Object-Orienred Analysis OOA)

发⽣在需求分析阶段,解决“做什么”的问题,主要任务是确定对象的属性与⽅法,对象与对象之间的关系,各个操作的具体流程,但不考虑系统具体实现有关的因素

2> 面向对象设计(Object-Oriented Design OOD)

发⽣在系统设计阶段,解决的是“怎么做”的问题,其基本思想包括抽象、封装和可扩展性,其中可扩展性主要通过继承和多态来实现。主要任务是把实现对象进⾏⼯程化规范,管理程序内部各部分的相互依赖,为⾯向对象编程提供指导与依据.(属性和动作划分到类里面)

3> 面向对象编程(Object-Oriented Programming OOP)

发⽣在系统开发阶段,使⽤⾯象对象语⾔如JAVA,实现OOD模型中的各个成分;OOP的三个主要⽬标是:重⽤性,灵活性和扩展性。(把设计出来的东西进行实现)

面向对象的特征: 封装, 继承, 多态
 

3. C/S, B/S 架构

• C/S架构即客⼾端 / 服务器架构模式

• B/S架构即浏览器 / 服务器架构模式

CS架构

C/S 架构全称是客⼾端 / 服务器(Client / Server)架构,是常⽤的两层架构。客⼾端需要安装客⼾端软件,服务端程序运⾏在服务器上,提供Socket或数据库服务。
 

常⽤于固定⽤⼾群体中。常⻅的C/S架构的应⽤,⽐如QQ,CCTALK,各种⽹络游戏等等,⼀般需要安装并且与服务器进⾏⽹络通信的都属于此类。

优点:

• ⼤部分业务都可以在客⼾端完成,充分利⽤本地的计算机资源

• 响应速度快

• 个性化定制能⼒强

• ⾯向相对固定的⽤⼾群,对信息安全的控制能⼒强

缺点:

• 需要安装客⼾端才能使⽤

• 维护成本⾼,任何⼀台电脑上的客⼾端出现问题都需要进⾏维护,升能过程繁琐

BS架构

B/S架构全称是浏览器 / 服务器(Browser/Server)结构,分为Web浏览器、服务器程序、数据库服务三部分,可以理解为是对C/S架构⼀种改进,我们此时只需要安装浏览器即可。由于所有的业务逻辑都由服务器程序处理,所以客⼾端仅使⽤浏览器就可以完成所有操作,⼤⼤降低了客⼾端的维护成本。(不像c/s,更新要每个用户都进行更新)

常⽤于对公开⽤⼾提供的⽹络服务中。⽐如常⻅的⼤型⽹站都属于此类。优点:

• 客⼾端零维护,只需要安装⼀个浏览器即可

• 所有业务都集中在服务器端,业务扩展⾮常⽅便

• 维护成本低,只需要维护服务器即可

缺点:

服务器安全与业务处理能⼒需要花费很⼤精⼒与成本(无法分辨访问的是普通用户,还是黑客)

• 不同浏览器⽀持不尽⼈意(服务器的兼容性)

我们这个项目是基于BS来进行开发的

相关技术及工具

服务端技术

◦ Spring

◦ Spring Boot

◦ Spring MVC

◦ MyBatis

浏览器端技术

◦ HTML, CSS, JavaScript

◦ jQuery

◦ Bootstrap

数据库

◦ MySQL

项目构建工具

◦ Maven

版本控制工具

◦ Git + GITEE

软件需求

在软件⽣命周期中需求分析是⾮常重要的⼀步,在进⾏需求分析前,先了解⼀下需求的分类以及如何获取需求

需求分类

a. 业务需求:指反映企业或客⼾对系统的⽬标要求,通常来⾃与企业内部。(系统要实现最基本的功能)

b. ⽤⼾需求:描述的是⽤⼾的具体⽬标,或⽤⼾要求系统必须能完成的任务。(主要是用户提出的需求)

c. 系统需求:从系统⻆度来说明软件的需求,包括功能需求(系统必须实现的功能)、⾮功能需求(⽐如软件的质量,可维护性,效率等等)和设计约束(交付时的⼀些限制条件,⽐如必须采⽤国有⾃主知识产权的数据库,必须运⾏在某个操作系统下)等等。

需求获取

需求获取(用户和开发人员的沟通过程)的⽅式主要有以下⼏种:

a. ⽤⼾访谈:最基本的⽅式。

b. 问卷调查:由于对⽤⼾进⾏逐⼀访谈⽐较耗时且⽤⼾时间不⼀定允许及时参与访谈,所以可以

预先准备问卷调查表让⽤⼾填写,再根据结果进⾏⼩范围访谈,可以看做是对⽤⼾访谈的⼀种优化。

c. 采样:对特定种群进⾏采样,研究所选出的样本,得到有⽤信息。对于信息系统的开发,现在⽂档就是采样种群。

d. 情节串联板:通过⼀系统图⽚、幻灯⽚来进⾏讲解,说明系统应该如何运⾏

需求分析

获取需求后,进⾏具体的需求分析⼯作,最终形成软件需求规格说明书(需求文档)做为向下⼀个阶段交付的成.


需求分析的内容

a. 绘制系统上下⽂范围关系图:⽤于定义系统与系统外部实体间界限和接⼝的简单模型,为需求

确定范围

b. 创建⽤⼾界⾯原型:可以通过快速开发⼯具开发⼀个原型或者通过幻灯⽚、Flash等演⽰⼯具制作⼀个演⽰原型,甚⾄可以通过纸笔画出⼀些关键的界⾯接⼝⽰意图,从⽽帮助⽤⼾更好的理解要解决的问题,理解系统;

c. 分析需求的可⾏性:对获取到的需求进⾏成本、性能和技术实现⽅⾯的可⾏性研究,以及是否与其他的需求存在冲突,是否有对外部的依赖等;

d. 确定需求的优先级:是制订迭代计划的⼀个重要的依据,可以使⽤满意和不满意指标进⾏说明。满意度表⽰当需求被实现时⽤⼾的满意程度,不满意度表⽰当需求未被实现时⽤⼾的不满意程度;

e. 为需求建⽴模型:表现形式主要是图表加上少量的⽂字描述,图形化的描述使需求更加清晰、易懂。需求分析模型主要描述系统的数据、功能、⽤⼾界⾯和运⾏的外部⾏为,并不会涉及软件的具体实现细节,同时,为后续的软件设计提供了系统的表⽰视图

f. 创建数据字典:对系统⽤到的所有数据项和结构进⾏定义,以确保开发⼈员使⽤统⼀的数据定义(比如自定义的错误码)

面向对象分析(OOA)

        OOA的基本任务是运⽤⾯象对象⽅法,对问题域进⾏分拆和理解正确认识事物间的关系,找出描述问题域和系统功能的类和对象,定义它们的属性和职责(类中的属性和方法),以及它们之间形成的各种联系(对象和对象之间的依赖)

UML统一建模语言

UML(Unified Modeling Language)是⼀种易于表达、功能强⼤且普遍适⽤的建模语⾔,描述类和类之间的关系,它的作⽤不限于⽀持OOA和OOD,还⽀持从需求分析开始的软件开发全过程。

UML的重要组成部分:

◦ 事物:事物也称为建模元素,包括结构事物、⾏为事物、分级事物和注释事物,这些事物是UML模型中最基本的OO构造块;

◦ 关系:UML⽤关系把各个事物结合在⼀起,主要的关系有:依赖(dependency)(类与类之间的相互注入)、关联(association)(和依赖差不多一个意思)、泛化(generalization)(父子类的关系)、实现(realization)(实现类和接口的关系);

◦ 图:主要包括类图、对象图、构件图、组合结构图、⽤例图、顺序图、通信图、定时图、状态图、活动图、部署图、制品图、包图、交互概览图

用例模型

从⽤⼾的⻆度来看,他们并不想了解系统的内部结构和设计,他们关⼼的是系统所能提供的服务,把从⽤⼾那⾥获取的需求记录下来,进⾏合成与提炼,从⽽建⽴⽤例模型。在OOA⽅法中,构建⽤例模型⼀般需要经历以下阶段分别的,识别参与者、合并需求获得⽤例、细化⽤例描述和调整⽤例模型,其中前三个阶段是必需的

1> 用例图的元素

⽤例是⼀种描述系统需求的⽅法,在⽤例图中,主要包括参与者、⽤例和通信关联三种元素:如图所⽰

◦ 参与者:参与者是指存在于系统外部并与系统进⾏交互的任何事物,既可以是使⽤系统的⽤⼾,也可以是其他外部系统和设备等;

◦ ⽤例:指在系统中执⾏的动作,这些动作将⽣成参与者可⻅的结果。也就是说⽤例表⽰系统所提供的服务(比如论坛系统提供的发布帖子, 删除帖子这个功能),它定义了系统是如何被参与者所使⽤,描述的是参与者为了使⽤系统提供的服务与使⽤发⽣的⼀段对话;

◦ 通信关联:表⽰的是参与者和⽤例之间的关系(用户发布了帖子),或者⽤例与⽤例之间的关系。箭头所指⽅是对话的被动接受者,箭尾所指⽅是对话的主动发起者,如果不想强调对话中的主动与被动关系,可以使⽤不带箭头的关系实线

2> 识别参与者

参与者是与系统交互的所有事物(和系统相关的角色),不仅可以由⼈承担,还可以是其他系统和硬件设备,要注意的是,参与者⼀定在系统之外,不是系统的⼀部分。执⾏系统功能的参与者可能有多个,有主次之分,开发⽤例的主要⽬的是找到主要参与者。

可以通过下列问题来帮助分析和发现系统的参与者:谁使⽤这个系统?谁安装这个系统?谁启动这个系统?谁维护这个系统?谁关闭这个系统?哪些系统使⽤这个系统?谁从这个系统获取信息?谁为这个系统提供信息?

◦ 示例:

我们以当前准备开发的论坛系统为例,前期获取到如下⽤⼾需求:

▪ 注册登录 使用论坛的普通用户

▪ 帖⼦列表, 发布帖⼦, 删除帖⼦, 回复帖⼦等功能.   系统中的具体功能

▪ ⽀持个⼈主⻚的展⽰/编辑, ⽀持头像上传. 系统中的具体功能

▪ ⽀持帖⼦按版块分类. 系统中的具体功能

▪ ⽀持发布图⽚表情 系统中的具体功能

▪ ⽀持站内私信 系统中的具体功能

▪ 管理员可以添加/删除/修改版块 系统中的具体功能    管理员是特殊用户

▪ 管理员可以管理所有帖⼦

综合以上需求描述,可以明显的提到到两个参与者,⼀个是管理员,⼀个是普通⽤⼾

3> 合并需求获得用例

将参与者都找到之后,接下来就要仔细检查参与者,为每个参与者确定⽤例。

⾸先,要将获取到的需求分配给参与者(哪个角色可以使用系统中的哪些功能),⽐如,普通⽤⼾可以进⾏注册,登录,编辑个⼈信息,发贴⼦,修改⾃⼰发的贴⼦,发站内信等等,管理员不仅可以进⾏普通⽤⼾的操作还可以进⾏版块管理等等。

其次,进⾏需求合并操作,并产⽣⽤例(把需求描述成系统中的具体动体),⽐如对于帖⼦来说,可以相关的操作描述成具体的动作如:发布帖⼦,修改帖⼦,删除帖⼦(这些都是用例),在这⾥合并为操作帖⼦。注:⽤例并不需要包括具体的操作流程(事件流),事件流将在细化⽤例描述中体现。

然后,将识别到的参与者和合并⽣成的⽤例通过⽤例图的形式表⽰出来,⾄此以获得⽤例模型的框架。如下图所⽰:

 4> 细化用例描述

⽤例描述可以迭代完成,先对⼀些重要的⽤例编制相对细致的描述,对于那些不重要的⽤例可以留待以后再补充完成,⽤例描述通常包括⽤例名称、简要说明、事件流、⾮功能需求、前置和后置条件、扩展点、优先级

以操作帖⼦⽤例中的发布帖⼦为例,有如下描述:

1. ⽤例名称发布帖⼦
2. 简要说明⽤⼾发布新帖,同时增加对应版块帖⼦数量
3. 事件流

1. ⽤⼾向系统发出发布新贴请求

2. 系统展⽰编辑新帖界⾯

3. ⽤⼾选择对应的版块类别,写⼊帖⼦标题与正⽂,并提交

4. 系统检查版块类别、标题、正⽂是否有效

5. 系统将所输⼊的信息存储建档,帖⼦发布成功  (主要描述这个用例的执行过程)

4. 备选事件流
5. ⾮功能需求⽆特殊要求
6. 前置条件⽤⼾必须登录系统进⾏权限校验
7. 后置条件修改对应版块下帖⼦的数量,修改⽤⼾发帖数
8. 扩展点
9. 优先级最⾼(满意度5,不满意度5)

针对以上⽤例细化描述⽰例可知,⽤⼾发贴前要对登录状态进⾏检查,发贴操作中包含⾝份检验,⾝份检查在其他操作中也都会涉及,所以我们抽象出⼀个⾝份检验的⽤例,使⽤⽤例图描述⽤例之间的关系如下所⽰:

分析模型 

1> 定于概念类

概念类:模型中可以代表事物与概念的对象。(java中的类, 也就是数据库中的表)

OOA的主要任务就是找到系统中的对象和类,这些类将反映到OOD中的软件类和OOP中具体的实现类。

发现类的⽅式有很多种,其中应⽤最⼴泛的是名词短语法,具体步骤如下:

▪ 阅读和理解需求⽂档或⽤例描述

筛选出名词或名词短语,建⽴初始类清单(候选类)

▪ 将候选类分为三类:分别是显⽽易⻅的类,明显⽆意义的类和不确定类别的类

▪ 舍弃明显⽆意义类别的类

▪ ⼩组讨论不确定类别的类,直到把他们合并或调整到其他两个类别。

根据之前按的内容,发布帖⼦⽤例的事件流,可以获取到候选概念类的清单,如下:

名词类别概念类列表
显⽽易⻅的类⽤⼾,帖⼦,版块 (最终得到三个概念类)
⽆意义的类系统,界⾯,信息
不确定类别的类版块类别,版块帖⼦数量,帖⼦标题,帖⼦正⽂,权限

 经过简单分析:“版块类别” 和 “版块帖⼦数量” 都可以归结到 “版块” 类,做为 “版块” 类的属性;“帖⼦标题” 和 “帖⼦正⽂” 都可以归结到 “帖⼦” 类,做为 “帖⼦” 类的属性;“权限” 可以归结到 “⽤⼾”类,做为“⽤⼾”类的属性。⾄此,针对发布帖⼦这个⽤例,就确定了三个类,分别是:⽤⼾、版块、帖⼦。

2> 确定类之间的关系

当完成了类的寻找⼯作之后,就是理清这些类之间的关系,类之间的关系有:关联、依赖、泛化、聚合、组合和实现,他们在UML中的表⽰⽅式如下:

关联关系:提供不同类的对象之间的结构关系,⽽不是类与类之间的关系,两个对象之间⼀般以动词连接,⽐如,⽤⼾-发布-帖⼦可以⽤⼀个箭头连接,表⽰关联关系对象可以从⼀个端得到另⼀端对象,如果没有箭头,认为是⼀个双向关系或是⼀个未定义的关联;(司机 驾驶 汽车 可以使用->)(张三 聊天 李四 没有箭头)

依赖关系两个类A 和 B,如果B变化可能会引起A的变化,则称类A依赖与B,⽐如,⼀个类另⼀个类的数据成员,⼀个类是另⼀个类的某个操作的参数等;(Spring DI Controller 依赖 Service 依赖 DAO)

聚合关系:共享聚集关系通常简称为聚合关系,他表⽰了类之间整体与部分的关系“部分”可以属于不同的“整体”,“部分”与“整体”的⽣命周期可以不同,⽐如,汽⻋和⻋轮就是聚合关系,⼀个汽有⼀多个轮⼦,汽⻋坏了,轮⼦还可以⽤,轮了坏了可以再换⼀个;

组合关系:组合聚集关系通常简称为组合关系,他也表⽰类之间整体与部分的关系与聚合关系的区别在于,组合关系中的“部分”只能属于⼀个“整体”,“部分”与“整体”的⽣命周期相同,⽐如:⼀个公司有多个部⻔,他们之间就是组合关系,公司⼀旦倒闭,部分也就不存在了;

实现关系:描述的是类和接⼝之间的关系(实现类),⼀个类可以实现接⼝中声明的⽅法;

泛化关系:描述的是⽗类与⼦类之间的关系,继承关系是泛化关系的反关系,也就是说⼦类继承了⽗类,⽽⽗类是⼦类的泛化。

对于⽤⼾发布帖⼦的⽤例,在确定类与类之间关系之后,可以⽤UML的类图把这些关系记录下来,如下图所⽰:⽤⼾发布帖⼦,帖⼦聚合成版块,版本组成了论坛

 

3> 为类添加职责 

在找到概念类并且理清了他们之间的关系后,就可为类添加职责(为类添加属性和方法),主要包括两⽅⾯内容:

▪ 类所维护的知识,即成员变量或属性

• 注意要保持属性的简单性,即:只定义与系统责任和⽬标相关的属性;使⽤简单数据类型定义;不为类关联定义属性。(属性和类强相关)

▪ 类能够执⾏的⾏为,即成员⽅法或责任

• 可以根据动词来判断,再进⾏筛选,与识别类的过程类似。

这个阶段只找出⼀些主要的、明显、与业务规则相关的部分,切忌在这个阶段不断地细化

根据分析得出的类的职责,⽤类图表⽰如下:

论坛系统的类图, 用户 模块 板块 之间的类图关系

这⾥根据⽤⼾、帖⼦、版块的关系⽤类图做⼀个简单的⽰例,详细设计将在项⽬开发章节按每个功能需求分别演⽰

建立交互图

多个对象的⾏为通常采⽤交互图来表⽰,UML中最常⽤的是顺序图,⼏乎可以⽤在任何系统的场景。

顺序图的基本元素有对象、参与者、⽣命线、激活框、消息和消息线,其中消息是顺序图的灵魂。以⽤⼾登录过程为例,使⽤顺序图描述如下:

各个元素

软件需求规格说明书(需求分析阶段的成果)

通过识别参与者、合并需求获取⽤例、细化⽤例描述、定义概念类、确定类之间的关系、为类添加职责、建⽴交互图等步骤,已经完成了需求的定义,并把现实世界中的事物抽象成了⾯向对象中的类,同时也确定了系统的主要功能和范围,上述的⼯作是编写软件需求规格说明书的基础,只要这些需求汇总起来就形成了软件需求规格说明书中的需求部分。

软件需求规格说明书做为需求分析阶段交付的成果,对系统设计与系统开发有重要的指导意义,它的具体组成部分,如:范围、引⽤⽂件、需求、合格性规定、需求可追踪性、尚未解决的问题、注解、附录等有关内容的详细介绍: 国家标准|GB/T 8567-2006

 系统设计

技术选型

⽬标:确定技术平台以及开发和部署相关⼯具及版本(统一开发环境, 测试环境, 生产环境相关依赖的版本)

类别描述
构架基于MVC构架,实现前后端分离
编码格式UTF-8
前后端交互数据格式JSON
JDK版本JDK17
服务器端技术SpringBoot 2.7.6 Spring MVC MyBaits Start 2.3.0
浏览器端技术HTML, CSS, JavaScript jQuery3.x Bootstrap
数据库MySQL8.0
项⽬构建⼯具Maven 3.8.x
版本控制⼯具Git 2.36.0 及以上 + GITEE
开发⼯具IntelliJ IDEA社区版 2022.1.3
API⽂档⽣成⼯具Swagger Springfox 3.0.0

设计数据库实体

通过需求分析获得概念类并结合业务实现过程中的技术需要,设计出数据库实体


数据库设计

数据库名: forum_db

公共字段:⽆特殊要求的情况下,每张表必须有⻓整型的⾃增主键,删除状态、创建时间、更新时间,如下所示:

删除操作不是真正的删除而是把state通过update语句从0 -> 1

表的设计

运⽤分析模型章节中定义概念类的⽅法,能过观察现在的论坛并结合具体业务需要完成类的定义

1. 确定论坛中的类 对应到数据库中的表

第一个类: 用户类

第二个类: 帖子

第三个类: 板块

第四个类: 帖子的回复

第五个类: 站内信

2. 为类确定属性 

要求: 与类强相关, 可以用简单类型去表示

1> 用户类: 用户名(登录用的), 昵称(在论坛中显示), 密码(在数据库中存明文还是密文(MD5->各种字符的组合生成一个字典->生成MD5字符串->生成一个以密文为Key,明文为Value的哈希表)), 头像地址, 是否为管理员, 发帖数, 邮箱地址, 注册日期,电话, 个人简介,盐值(随机字符)( 关于为什么有了昵称还要用户名, 是为了防止黑客通过昵称猜到我们的用户名

因为简单的md5密文也会不安全, 因此我们需要使用随机字符和明文拼接然后进行md5加密

2> 板块类: 板块名, 排序, 板块下的帖子数量

3> 帖子: 作者ID (需要和用户表建立关联关系), 发布时间, 访问次数, 点赞次数, 回复次数,帖子标题, 正文, 板块ID (需要和板块表建立关联关系)

4> 帖子回复: 回复用户Id(需要和用户表建立关联关系), 回复内容, 回复时间, 主贴的ID (需要和帖子表建立关联关系)

5> 站内信(发私信): 发送者用户ID(需要和用户表建立关联关系), 接收者用户ID(需要和用户表建立关联关系), 内容, 发送时间

1> 用户表: t_user

3> 板块表: t_board

4> 帖子表: t_article

5> 帖子回复表: t_ariticle_reply

6> 站内信表: t_message

创建数据库的sql语句

注意: 编写sql的时候, 把字段名从文档中复制出来, 尽量不要用手写

# 创建数据库
drop database if exists forum_db_001;
create database forum_db_001 character set utf8mb4 collate utf8mb4_general_ci;
# 选择数据库
use forum_db_001;# 创建表
# 用户表
drop table if exists t_user;
create table t_user (id bigint primary key auto_increment comment '编号,主键自增',username varchar(20) not null unique comment '用户名,唯一',password varchar(32) not null comment '加密后的密码',nickname varchar(50) not null comment '昵称',phoneNum varchar(20) comment '手机号',email varchar(50) comment '电子邮箱',gender tinyint not null default 2 comment '性别 0女,1男,2保密',salt varchar(32) not null comment '为密码加盐',avatarUrl varchar(255) comment '用户头像路径',articleCount int not null default 0 comment '发帖数量',isAdmin tinyint not null default 0 comment '是否管理员 0否,1是',remark varchar(1000) comment '备注,自我介绍',state tinyint not null default 0 comment '状态 0正常,1禁言',deleteState tinyint not null default 0 comment '是否删除,0否,1是',createTime datetime not null comment '创建时间,精确到秒',updateTime datetime not null comment '更新时间,精确到秒'
);# 版块表
drop table if exists t_board;
create table t_board (id bigint primary key auto_increment comment '编号,主键自增',name varchar(50) not null comment '版块名',articleCount int not null default 0 comment '帖子数量',sort int not null default 0 comment '排序优先级,升序',state tinyint not null default 0 comment '状态 0正常,1禁用',deleteState tinyint not null default 0 comment '是否删除,0否,1是',createTime datetime not null comment '创建时间,精确到秒',updateTime datetime not null comment '更新时间,精确到秒'
);# 帖子表
drop table if exists t_article;
create table t_article (id bigint primary key auto_increment comment '编号,主键自增',boardId bigint not null comment '编号,主键自增',userId bigint not null comment '发帖人,关联用户编号',title varchar(100) not null comment '帖子标题',content text not null comment '帖子正文',visitCount int not null default 0 comment '访问量',replyCount int not null default 0 comment '回复数',likeCount int not null default 0 comment '点赞数',state tinyint not null default 0 comment '状态 0正常,1禁用',deleteState tinyint not null default 0 comment '是否删除,0否,1是',createTime datetime not null comment '创建时间,精确到秒',updateTime datetime not null comment '更新时间,精确到秒'
);# 帖子回复表
drop table if exists t_article_reply;
create table t_article_reply (id bigint primary key auto_increment comment '编号,主键自增',articleId bigint not null comment '关联帖子编号',postUserId bigint not null comment '楼主用户,关联用户编号',replyId bigint comment '关联回复编号,支持楼中楼',replyUserId bigint comment '楼主下的回复用户编号,支持楼中楼',content varchar(500) not null comment '回贴内容',likeCount int not null comment '回贴内容',state tinyint not null default 0 comment '状态 0正常,1禁用',deleteState tinyint not null default 0 comment '是否删除,0否,1是',createTime datetime not null comment '创建时间,精确到秒',updateTime datetime not null comment '更新时间,精确到秒');# 站内信表
drop table if exists t_message;
create table t_message (id bigint primary key auto_increment comment '编号,主键自增',postUserId bigint not null comment '发送者,关联用户编号',receiveUserId bigint not null comment '接收者,关联用户编号',content varchar(255) not null comment '内容',state tinyint not null default 0 comment '状态 0正常,1禁用',deleteState tinyint not null default 0 comment '是否删除,0否,1是',createTime datetime not null comment '创建时间,精确到秒',updateTime datetime not null comment '更新时间,精确到秒'
);-- 写入版块信息数据
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES
(1, 'Java', 0, 1, 0, 0, '2023-06-25 10:25:55', '2023-06-25 10:25:55');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES
(2, 'C++', 0, 2, 0, 0, '2023-06-25 10:25:56', '2023-06-25 10:25:56');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES
(3, '前端技术', 0, 3, 0, 0, '2023-06-25 10:25:56', '2023-06-25 10:25:56');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES
(4, 'MySQL', 0, 4, 0, 0, '2023-06-25 19:05:22', '2023-06-25 19:05:22');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (5, '面试宝典', 0, 5, 0, 0, '2023-06-25 19:05:22', '2023-06-25 19:05:22');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (6, '经验分享', 0, 6, 0, 0, '2023-06-25 19:05:22', '2023-06-25 19:05:22');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES
(7, '招聘信息', 0, 7, 0, 0, '2023-06-25 19:05:22', '2023-06-25 19:05:22');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (8, '福利待遇', 0, 8, 0, 0, '2023-06-25 19:05:22', '2023-06-25 19:05:22');
INSERT INTO `t_board` (`id`, `name`, `articleCount`, `sort`, `state`, `deleteState`, `createTime`, `updateTime`) VALUES (9, '灌水区', 0, 9, 0, 0, '2023-06-25 19:05:22', '2023-06-25 19:05:22');

 软件开发

搭建环境

确定JDK 版本为 17

确定MySQL版本为8.0

或者: select version();

检查 Maven

安装maven: 3.8以上

JDK17+maven下载安装,settings.xml文件配置_jdk17下载地址-CSDN博客

显示

修改一些maven的镜像, 并且xml下修改respority的路径

    <mirror><id>aliyun-public</id><mirrorOf>*</mirrorOf><name>aliyun public</name><url>https://maven.aliyun.com/repository/public</url></mirror><mirror><id>aliyun-central</id><mirrorOf>*</mirrorOf><name>aliyun central</name><url>https://maven.aliyun.com/repository/central</url></mirror><mirror><id>aliyun-spring</id><mirrorOf>*</mirrorOf><name>aliyun spring</name><url>https://maven.aliyun.com/repository/spring</url></mirror>

把你ideal下面的maven也修改一下

此时就是

检查GITEE

git --version

安装插件

Spring Boot Helper 创建Spring Boot 工程

⽤于创建Spring Boot 项⽬,由于插件最新版本是收费的,这⾥我们下载他的历史免费版本,但是对Idea的版本有限制,注意插件和Idea版本要匹配

插件地址:Spring Boot Helper - IntelliJ IDEs Plugin | Marketplace

要钱,我找了个激活码: https://web.52shizhan.cn/paid-activate-code 去这里付费27块钱可以永久使用

安装lombok

⽤于⽀持lombok语法

创建gitee仓库

获取地址

创建一个空项目, 然后进入cmd, 输入命令

git clone https://gitee.com/li_xiao_bai111/form.git

然后就会发现空目录下出现了gitee

创建工程

在刚刚创建gitee的目录下我们创建工程

其他的设置:

a. 修改编码格式为UTF-8: Settings --> Edit --> File encodings 

b. 检查或配置代码⾃动补全功能: Settings --> Edit --> General --> code completion

c. 检查或配置⾃动导包:Settings --> Edit --> General --> auto import

d. 检查或配置Maven,可以⽤国内仓库镜像:Settings --> Build, Execution & Deployment --

> Build Tools --> Maven

e. idea识别Maven项⽬:在Notifications视图中会提⽰Load Maven Project,点击即可。

开启热部署

修改代码后不需要重启

勾选下面的选项

在maven下面加入下面配置

<properties><!--jdk版本号--><java.version>17</java.version><!-- 编译环境JDK版本 --><maven.compiler.source>${java.version}</maven.compiler.source><!-- 运⾏环境JVM版本 --><maven.compiler.target>${java.version}</maven.compiler.target><!-- 构建项⽬指定编码集 --><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>

 配置yml/properties文件

spring:application:name: 论坛系统output:ansi:enabled: ALWAYS # 控制台输出彩⾊⽇志
server:port: 8080 #自定义的服务端口号#日志信息
logging:level:root: info # 日志的默认级别org.xiaobai.forum: debug # 指定包下的日志级别file:path: D:/forum_system/log # 日志保存路径pattern: MM-dd-HH:mm:ss #日期显示格式

测试

访问问指定的接口

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/80264.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/80264.shtml
英文地址,请注明出处:http://en.pswp.cn/bicheng/80264.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

架构师面试(三十七):监控系统架构模式

题目 监控是在产品生命周期的运维环节&#xff0c;能对产品的关键指标数据进行【实时跟踪】并对异常数据进行【实时报警】。 一句话描述&#xff0c;监控系统可以帮我们【主动预防和发现】业务系统中的问题。 我们常说&#xff0c;监控系统是 “粮草”&#xff0c;业务系统是…

【面试 · 二】JS个别重点整理

目录 数组方法 字符串方法 遍历 es6 构造函数及原型 原型链 this指向 修改 vue事件循环Event Loop FormData 数组方法 改变原数组&#xff1a;push、pop、shift、unshift、sort、splice、reverse不改变原属组&#xff1a;concat、join、map、forEach、filter、slice …

深度学习里程碑:AlexNet 架构解析与核心技术详解

内容摘要 本文深度解析2012年ILSVRC冠军模型AlexNet&#xff0c;全面阐述其在深度学习发展中的关键突破。从模型架构出发&#xff0c;详细解析卷积层、池化层、全连接层的数学原理&#xff0c;重点分析ReLU激活函数、LRN局部归一化、重叠池化等创新技术的数学表达与工程价值。…

第5章 深度学习和卷积神经网络

深度学习是人工智能的一种实现方法。本章我们将考察作为深度学习的代表的卷积神经网络的数学结构。 5-1小恶魔来讲解卷积神经网络的结构 深度学习是重叠了很多层的隐藏层&#xff08;中间层&#xff09;的神经网络。这样的神经网络使隐藏层具有一定的结构&#xff0c;从而更加…

JVM——JVM是怎么实现invokedynamic的?

JVM是怎么实现invokedynamic的&#xff1f; 在Java 7引入invokedynamic之前&#xff0c;Java虚拟机&#xff08;JVM&#xff09;在方法调用方面相对较为“僵化”。传统的Java方法调用主要依赖于invokestatic、invokespecial、invokevirtual和invokeinterface这四条指令&#x…

STM32教程:ADC原理及程序(基于STM32F103C8T6最小系统板标准库开发)*详细教程*

前言: 本文章介绍了STM32微控制器的ADC外设,介绍了ADC的底层原理以及基本结构,介绍了ADC有关的标准库函数,以及如何编写代码实现ADC对电位器电压的读取。 可以根据基本结构图来编写代码 大体流程: 1、开启RCC时钟(包括ADC和GPIO的时钟,另外ADCCLK的分频器,也需要配置…

2025年APP安全攻防指南:抵御DDoS与CC攻击的实战策略

2025年&#xff0c;随着AI技术与物联网设备的深度渗透&#xff0c;DDoS与CC攻击的复杂性和破坏性显著升级。攻击者通过伪造用户行为、劫持智能设备、利用协议漏洞等手段&#xff0c;对APP发起精准打击&#xff0c;导致服务瘫痪、用户流失甚至数据泄露。面对这一挑战&#xff0c…

STM32的定时器

定时器的介绍 介绍&#xff1a;STM32F103C8T6微控制器内部集成了多种类型的定时器&#xff0c;这些定时器在嵌入式系统中扮演着重要角色&#xff0c;用于计时、延时、事件触发以及PWM波形生成、脉冲捕获等应用。 *几种定时器&#xff08;STM32F103系列&#xff09;&#xff1…

算法中的数学:约数

1.求一个整数的所有约数 对于一个整数x&#xff0c;他的其中一个约数若为i&#xff0c;那么x/i也是x的一个约数。而其中一个约数的大小一定小于等于根号x&#xff08;完全平方数则两个约数都为根号x&#xff09;&#xff0c;所以我们只需要遍历到根号x&#xff0c;然后计算出另…

不同OS版本中的同一yum源yum list差异排查思路

问题描述&#xff1a; qemu-guest-agent二进制rpm包的yum仓库源和yum源仓库配置文件path_to_yum_conf&#xff0c; 通过yum list --available -c path_to_yum_conf 查询时&#xff0c;不同的OS版本出现了不同的结果 anolis-8无法识别 centos8可以识别 说明&#xff1a; 1 测试…

如何使用极狐GitLab 软件包仓库功能托管 helm chart?

极狐GitLab 是 GitLab 在中国的发行版&#xff0c;关于中文参考文档和资料有&#xff1a; 极狐GitLab 中文文档极狐GitLab 中文论坛极狐GitLab 官网 软件包库中的 Helm charts (BASIC ALL) WARNING:Helm chart 库正在开发中&#xff0c;由于功能有限&#xff0c;尚未准备好用…

【PostgreSQL数据分析实战:从数据清洗到可视化全流程】3.1 数据质量评估指标(完整性/一致性/准确性)

&#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 &#x1f449; 点击关注不迷路 文章大纲 数据质量评估核心指标&#xff1a;完整性、一致性、准确性实战解析3.1 数据质量评估指标体系3.1.1 完整性&#xff1a;数据是否存在缺失1.1.1 核心定义与业务影响1.1.2 检测…

详解 FFMPEG 交叉编译 `FLAGS` 和 `INCLUDES` 的作用

FLAGS 和 INCLUDES这两行是 Android NDK 编译时的编译器选项&#xff0c;用于控制代码生成、优化、调试、安全性和头文件搜索路径。下面逐项详解&#xff1a; 1. FLAGS 详解&#xff08;编译器选项&#xff09; FLAGS 定义了传递给 C/C 编译器&#xff08;如 clang 或 gcc&…

【RK3588嵌入式图形编程】-Cairo-Cairo图形库支持后端

Cairo图形库支持后端 文章目录 Cairo图形库支持后端1、PNG图像后端2、PDF文件后端3、SVG文件后端4、GTK窗口支持Cairo库支持多种后端。在本文中,我们使用Cairo创建PNG图像、PDF文件、SVG文件,并在GTK窗口上绘制。 1、PNG图像后端 在第一个示例中,我们创建一个 PNG 图像。 …

【常用算法:排序篇】2.快速排序的算法精要

快速排序是算法领域的"九阳神功"&#xff0c;掌握其精髓能让你在算法修炼之路上突破瓶颈。 1. 快速排序的核心思想 快速排序&#xff08;Quicksort&#xff09;是一种基于分治思想的高效排序算法&#xff0c;核心步骤为&#xff1a; 选择基准值&#xff08;Pivot&…

在现代Web应用中集成 PDF.js (pdfjs-dist 5.2 ESM): 通过 jsdelivr 实现动态加载与批注功能的思考

PDF 文档在现代 Web 应用中越来越常见&#xff0c;无论是作为文档预览、报告展示还是在线编辑的载体。Mozilla 的 PDF.js 是一个功能强大的 JavaScript 库&#xff0c;它使得在浏览器端渲染和显示 PDF 文件成为可能&#xff0c;无需依赖原生插件。 本文将深入探讨如何在你的项…

基于FPGA控制ADC0832双通道采样+电压电流采样+LCD屏幕显示

基于FPGA控制ADC0832双通道采样电压电流采样LCD屏幕显示 前言一、芯片手册阅读1.SPI通信时序 二、仿真分析三、代码分析总结视频演示 前言 定制 要求使用ADC0832芯片进行ADC采样。其中电压采样以及电流采样是固定电路&#xff0c;是硬件设计&#xff0c;跟软件没没关系。本质上…

生产部署方案pm2配合python3脚本

前言 使用python3来处理redis 消息队列&#xff0c;记录下生产部署方案 「生产部署方案」&#xff1a; 多进程&#xff08;动态扩容&#xff09;无限自愈日志自动压缩系统级守护可多队列多worker 终极稳健版&#xff1a;PM2 Logrotate 自动扩容 守护链 适合&#xff1a…

Python全流程开发实战:基于IMAP协议安全下载个人Gmail邮箱内所有PDF附件

文章目录 一、需求分析与安全前置&#xff1a;为什么需要专用工具&#xff1f;1.1 痛点场景1.2 技术方案选择 二、准备工作&#xff1a;Gmail账号安全配置与环境搭建2.1 开启两步验证&#xff08;必做&#xff01;&#xff09;2.2 创建应用专用密码&#xff08;替代普通密码&am…

巧用python之--模仿PLC(PLC模拟器)

工作中用到了VM(VisionMaster4.3)有时候需要和PLC打交道,但是PLC毕竟是别人的,不方便修改别人的程序,这时候需要一个灵活的PLC模拟器是多么好呀! 先说背景: PLC型号 汇川Easy521: Modbus TCP 192.168.1.10:502 在汇川Easy521中Modbus保持寄存器D寄存器 ,在modbus协议中 0-4区…