前置知识
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 #日期显示格式
测试
访问问指定的接口