计算机技术与科学技术论文八千字——基于SSM的个人笔记管理系统的设计与实现
1.软件需求分析
1.1.综合描述
1.1.1.产品的功能
个人笔记管理系统的设计与实现是将计算机网络技术与笔记结合起来进行的。个人笔记管理系统主要为通过网络学习的使用者提供笔记随时随地可以记录的功能,学习者也可以在平时闲暇时候复习自己已有的笔记,并可在自己感兴趣的笔记下发表自己的理解和感悟,通过不同笔记的分享学习者可以互相交流,互相学习,从而可以从多方面看待问题,进一步完善提高自己的知识水平。
1、游客:
(1)游客游览笔记:进入本系统主界面无需登录就可浏览到已经记录的笔记。
(2)游客查看笔记:无需登录点击查看笔记就可以看到笔记的标题、关键字、内容等,还可以看到之前发表过的评论。
(3)游客评论笔记:无需登录,在查看笔记详情界面可以对自己感兴趣部分发表评论,需要输入自己的名称以及评论内容。
2、管理员:
(1)帐号登录:管理员可以输入数据库中已有的账号以及就相对应的密码进行系统登录。
(2)新建笔记:登录成功后点击新建笔记,输入相对应的笔记标题、关键字、简介、内容等信息进行新建笔记。
(3)笔记管理:点击文章管理可以对已经存在的笔记进行删除修改操作。如点击编辑按钮可以对笔记的标题、关键字、简介、内容等进行修改操作。详情按钮可以查看已有笔记的各个内容。评论按钮可以查看对已有笔记发表过的评论,并可以对已有的评论进行删除。删除按钮可以对已存在的笔记进行删除。
(4)搜索笔记:可以模糊查询已经存在的笔记。
1.1.2.用户类和特性
游客主要进行浏览所有笔记、查看笔记具体内容、对感兴趣的笔记发表实时评论等功能
管理员主要进行账号登录、新建笔记、笔记管理、搜索笔记、查看评论、删除评论等功能。
1.1.3.运行环境
运行环境如表1.1所示。
表1.1 系统运行环境
|
版本 |
|
|
开发工具:IDEA |
IDEA 17.0.4 |
|
系统运行环境: |
JDK1.8 |
|
操作系统:Windows 10 |
专业版1577 |
|
数据库:MySQL |
5.1 |
|
Web服务器:Tomcat |
8.5 |
硬件环境配置要求较低,具体的配置如表1.2所示。
表1.2硬件环境表
|
服务器种类 |
最低配置 |
推荐配置 |
|
应用和数据库服务器 |
CPU:i5 4570 |
ICPU:i5 2GHz |
|
Mem:2GB |
Men:4GB |
|
|
HD:40D |
HD:120SSD |
|
|
前端访问硬件 |
ICPU:P42.0G |
ICPU:P42.8G |
|
Mem:521M |
Men:1G |
|
|
HD:80D |
HD:120D |
1.1.4.设计和实现上的限制
1、管理方针:指定甘特图控制项目进度,实现对开发周期与各资源的管理;
2、硬件配置见硬件环境,应配备web服务器,文本编辑工具等设备;
3、与其他应用间的接口:
使用Windows10操作系统,系统为B/S架构,应用服务器采用tomcat 8.0;
开发平台为:IDEA;
数据库为:mysql 5.1;
4、并行操作:可容许多个客户端访问系统并进行操作;
5、审查功能:所有设计必须符合ISO9002标准设计规范和软件开发从业者规范;
6、所需的高级语言:java语言,正确使用mysql语句;
7、通信协议:Http协议限制,TCP/IP通信协议,无线通讯协议限制;
8、应用的临界点:数据库表中各字段的长度约束,输入字符的长度、用户上传的数据大小的限制。
1.2.外部接口需求
1.2.1.后台界面布局
界面左上角为系统菜单区,陈列了管理员可以使用的全部功能。系统管理员可以通过鼠标单击按钮打开对应页面,进行相应的操作。
界面右上角有搜索框,管理员可以进行搜素。
功能布局如图1.1所示。
图1.1 功能布局
常用的功能区布局如图1.2所示。
当在系统菜单区处选择某个功能操作时(如文章管理),就会在功能区上弹出界面用来显示从数据库中查询出来的数据列表信息以及对已有信息可以进行的操作。
图1.2 功能布局
1.2.2.前台用户界面布局
前台的主页界面如图1.3所示,界面上方是信息导航栏,界面下方是已有笔记,点击阅读文章查看笔记详细内容。
图1.3游客主页布局
游客阅读笔记对笔记发表评论界面如图1.4所示,在评论框中输入评论内容后点击提交按钮。
图1.4游客评论页面
1.3.系统功能需求
1.3.1.角色说明
在分析了个人笔记管理系统之后,可以确定该系统有两个角色构成,分别是游客和管理员。以下是这两个角色的功能说明:
1、游客:
(1)游客浏览笔记:只可以查看管理员已经发表的笔记。
(2)游客查看笔记:游客可以看到笔记的标题、内容以及之前的评论,不能对已有评论进行操作。
(3)游客评论笔记:游客发表评论成功后会在笔记下方出现评论者的名称、发表时间、发表内容。
2、管理员:
管理员部分的功能可以概括为数据的维护功能,包括系统管理员数据的维护,笔记信息数据的维护,数据库信息数据的维护等。此外,由于操作员与管理员系统界面的不同,需要添加系统登录界面。
(1)、系统管理员管理:维护系统中所有管理员的信息和数据。
(2)、角色权限管理:维护系统中不同用户角色的功能菜单权限。
(3)、笔记信息管理:可以发布笔记的标题、关键字、简介、内容等信息。可以在游客界面展示。可以删除不需要的笔记,删除的笔记在游客界面看不到。可以修改笔记中的任意一个内容,修改成功后可以同步到游客界面。
(4)、管理员评论管理:查看游客的评论,对不合理的评论进行删除。
1.3.2.模块功能具体设计
本信息管理系统的实现主要由两个用户身份组成:游客用户和管理员用户。由于系统用户的角色不同,所使用的功能模块也相应不同。管理员可以根据需要对系统各功能模块进行维护和管理操作。系统结构图如图1.5所示:
图1.5系统结构图
1.3.3.游客管理模块
游客主界面可以看到管理员发表过的笔记的题目、关键字等信息,点击一篇笔记下方的查看笔记可以看到整篇笔记的所有内容,包括题目、关键字、简介、内容、之前发表过的评论。点击笔记下方的评论,输入相应的名称和评论内容,点击帖子提交后,评论会实时出现在笔记下方。
1.3.4.笔记管理模块
笔记管理包括笔记详情、笔记编辑、查看评论、删除笔记等功能,其中笔记详情可以查看笔记的所有相关信息,编辑笔记可以对笔记的相关信息进行修改,查看评论功能中有删除评论功能,可以删除一些不合理的评论。管理员可以点击不同按钮进行不同操作。
1.3.5.笔记查询模块
管理员可以通过模糊查询来查询笔记,在搜索框中输入相关笔记名称,查找到所有相关笔记。
1.3.6.评论管理模块
游客通过输入相关信息发表评论,传入到后台,管理员可以看到目前总的评论数,还可以看到具体每一条评论是谁发表、什么时间发表、发表了什么,管理员如果认为评论不合理,有权对评论进行删除。
1.4.其它非功能需求
本网站系统严格遵循软件开发的标准流程模式,采用MVC模式。后端数据库的开发采用了 MySQL,并采用了一个开源框架 Spring。该系统利用 JDBC驱动实现了与数据库的无缝对接,并利用了跨平台的web应用技术及 JSP技术,实现了对微机硬件的低需求。利用 maven, jQuery, spring,Struts2, mybatis以及 MySQL的数据库来同步进行开发。
1.4.1.可靠性
经过调试,个人笔记管理系统在当前环境中运行比较可靠。系统对部分输入数据提供验证提示,对输入的数据进行验证,避免因为提交错误数据而造成系统异常,甚至是损坏,并将系统中对笔记的相关功能的操作结果反馈给管理员,让后续的系统操作更加便利。
1.4.2.安全性
个人笔记管理系统中的笔记信息均是管理员的隐私信息,管理员需要通过数据库中已有的正确的账号和密码登录个人笔记管理系统,成功完成登录认证后才能使用系统的各种对笔记的操作功能。本系统采用高强度的加密模式,对关键核心的,管理员隐私的,这些相关数据都进行加密处理。如果系统被黑,或者被脱库,数据被拿走也不用担心。因为数据都是被加密过的。
1.4.3.可用性
软件是一种灵活的塑性介质系统,它大大促进了迭代分析、设计、构建和验证,而不是系统中常用的纯物理组件。迭代开发模型的每次迭代都向不断增长的软件基础添加材料(代码);扩展的代码库已经经过了测试,根据需要进行了重写,并被证明能够满足基本需求。
1.4.4.可扩充性
该系统可以根据具体情况的需要进行适当的增加或减少,并可以进行灵活的扩充,以适应各种各样的变化和新的情况。
1.4.5.经济可行性
首先从系统建立的经济分析来看,系统的研发只需要一台电脑,而随着个人计算机的广泛应用,如今几乎每个人手中都有一部移动电话,因此研发过程中所需要的费用也就大大降低了。
1.4.6.其他可行性
关于系统的软件开发许可。它们都使用了当前授权的免费许可证,并且界面的UI和系统使用的图像都是授权和自制的。不存在著作权问题,且法律也符合当前政府的响应号召,满足信息产业技术管理的实际使用和发展需要。设计和开发人员也满足了软件行业的需求。
1.5.性能需求
Tomcat服务器体积、MySQL数据库是轻量级的。
1.6.软件质量属性
该系统是:可用的;可扩充的;易于使用的;数据是安全的。
1.7.业务规划
我们的用户连接最好不超过系统测试的理论性能数量以及数据库的连接池设置数量个,这是由于使用Tomcat以及MySQL所导致的局限性。
2.软件概要设计
2.1.设计概述
该系统是利用计算机信息技术进行设计开发的,其主要的使用的语言为Java,并且在该系统中使用了SSM框架对相关的功能模块业务进行在线实现。本系统的设计与开发的主要目的,就是为了让使用者在学习的过程中,能够利用网络,随时随地的记录笔记。还可以在这个平台上,将自己对笔记的想法和想法进行分享,让使用者可以通过笔记的分享来相互借鉴,相互学习,从而提升自己学习的效率以及知识水平。
根据软件工程对软件开发的要求,详细分析了系统的各项功能和相关技术。采用结构化分析方法对问题进行自上而下、层层分解。预期的最终功能如下:
a.设计的使用界面简洁明了,用户操作简单快捷。b.对不同角色的用户有不同管理。c.方便信息的查询。d.基本信息管理。
系统的架构为三层体系结构,分别为表示层、业务逻辑层、数据访问层、实体类库。
2.2.系统逻辑设计
图2.1三层结构图
2.3.数据库设计
根据需要设计的系统功能设计数据库。我们需要建立一个数据库关系模型来存储这些数据信息。数据库中储存着海量的信息,是整个个人笔记管理系统的核心与基础。同时,该数据库还提供了增加,删除,校验,修改等功能,使得该系统可以快速地查找到需要的信息,而无需在程序中查找。在数据库中,各信息表按某种关系进行了严格的组合、排列、组合,最终形成了一个完整的数据表。
系统程序使用MySQL作为后台数据库支持,数据库包括以下数据库表:
本系统数据库名称为blog,数据库中包括:
1、管理员表(admin)
2、管理员登录日志表(admin_login_log)
3、文章表(article)
4、栏目表(catalog)
5、评论表(comment)
各表数据结构如下:
管理员表(admin)如表2.1所示,存储管理员账号密码
表2.1管理员表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
mediumint |
9 |
Y |
N |
管理员ID |
|
username |
varchar |
30 |
N |
N |
管理员名 |
|
password |
char |
32 |
N |
N |
管理员登录密码 |
管理员登录日志表(admin_login_log)如表2.2所示,存储登录日志
表2.2管理员登录日志表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
Bigint |
20 |
Y |
N |
日志ID |
|
admin_id |
Int |
11 |
N |
N |
管理员ID |
|
date |
timestamp |
0 |
N |
Y |
登录时间 |
|
ip |
varchar |
30 |
N |
Y |
登录地址 |
文章表(article)如表2.3所示,存储换货信息
表2.3文章表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
mediumint |
9 |
Y |
N |
笔记ID |
|
title |
varchar |
50 |
N |
Y |
笔记题目 |
|
keywords |
varchar |
150 |
N |
Y |
笔记关键字 |
|
desci |
varchar |
500 |
N |
Y |
笔记描述 |
|
pic |
varchar |
500 |
N |
Y |
笔记图片地址 |
|
content |
text |
0 |
N |
Y |
笔记详细内容 |
|
click |
mediumint |
9 |
N |
Y |
笔记点击量 |
|
time |
timestamp |
50 |
N |
Y |
笔记发表日期 |
栏目表(catalog)如表2.4所示,存储商品类别信息
表2.4栏目表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
mediumint |
9 |
Y |
N |
栏目ID |
|
name |
varchar |
30 |
N |
N |
栏目名称 |
|
keywords |
varchar |
150 |
N |
N |
栏目关键词 |
|
desc |
text |
0 |
N |
N |
栏目描述 |
|
type |
tinyint |
150 |
N |
N |
栏目类型0:列表;1:留言 |
评论表(comment) 如表2.5所示,存储退货信息
表2.5评论表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
bigint |
20 |
Y |
N |
评论ID |
|
article_id |
bigint |
20 |
N |
N |
笔记ID |
|
content |
text |
0 |
N |
Y |
评论内容 |
|
date |
timestamp |
0 |
N |
Y |
评论日期 |
|
name |
varchar |
10 |
N |
Y |
留言者名称 |
|
|
varchar |
30 |
N |
Y |
留言者邮箱 |
3.软件详细设计
3.1.界面设计
3.1.1.游客界面
下图界面是个人笔记管理系统的游客浏览界面,可以看到已经发表笔记的标题等部分内容,游客功能界面如图3.1所示:
图3.1游客界面
3.1.2.浏览笔记界面
点击游客界面的阅读全文可以看到该篇笔记的全部内容,包括标题、点击量、内容等,还可以进行发表评论。如图3.2所示:
图3.2浏览笔记界面
3.1.3.发表评论界面
游客阅读笔记是可以发表自己的想法,通过输入评论内容,留言者昵称、留言者邮箱后,点击提交进行评论的发表。如图3.3所示:
图3.3发表评论界面
3.1.4.管理员登录界面
管理员输入相应的账号密码进行登录,如图3.4所示:
图3.4管理员登录界面
3.1.5.管理员首页
管理员首页可以看到上次登录的时间、ip地址以及本次登录的ip地址,还可以看到已有笔记数量、评论数量以及登录次数。还有增删改查各个功能,点击相应操作按钮进行相关操作。如图3.5所示:
图3.5管理员首页
3.1.6.新建笔记页面
通过输入笔记标题、栏目、关键字、简介以及内容的详细信息进行添加新的笔记,如图3.6所示:
图3.6新建笔记页面
3.1.7.笔记管理页面
点击详情可以看到所有已存在的笔记,并且有详情、评论、编辑、删除四个按钮可以对笔记进行相对应的操作,如图3.7所示:
图3.7笔记管理页面
3.1.8.详情界面
点击详情可以看到该篇笔记的全部内容,包括id、标题、关键字、简介、发表时间、点击量、内容。如图3.8所示;
图3.8详情界面
3.1.9.编辑界面
点击编辑按钮可以对该篇笔记的相关内容进行修改操作,如图3.9所示:
图3.9编辑界面
3.1.10.评论界面
点击评论按钮可以看到所发表给该篇笔记的所有评论,在评论界面有删除按钮,点击删除按钮可以对不合理的评论进行删除操作。如图3.10所示:
图3.10评论界面
3.1.11.删除界面
点击删除按钮可以对不想要的笔记进行删除操作。如图3.11所示:
图3.11删除界面
3.1.12.搜索界面
在搜索框中输入想要搜索的笔记的标题或内容进行模糊查询操作,如图3.12所示:
图3.12搜索界面
3.2.数据库设计
3.2.1.数据库逻辑设计
用户逻辑设计的E-R图如图3.13所示:
图3.13 E-R图
3.2.2.数据库物理设计
本本系统数据库名称为blog,数据库中包括:
6、管理员表(admin)
7、管理员登录日志表(admin_login_log)
8、文章表(article)
9、栏目表(catalog)
10、评论表(comment)
各表数据结构如下:
管理员表(admin)如表3.14所示,存储管理员账号密码
表3.14管理员表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
mediumint |
9 |
Y |
N |
管理员ID |
|
username |
varchar |
30 |
N |
N |
管理员名 |
|
password |
char |
32 |
N |
N |
管理员登录密码 |
管理员登录日志表(admin_login_log)如表3.15所示,存储登录日志
表3.15管理员登录日志表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
Bigint |
20 |
Y |
N |
日志ID |
|
admin_id |
Int |
11 |
N |
N |
管理员ID |
|
date |
timestamp |
0 |
N |
Y |
登录时间 |
|
ip |
varchar |
30 |
N |
Y |
登录地址 |
文章表(article)如表3.16所示,存储笔记信息
表3.16文章表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
mediumint |
9 |
Y |
N |
笔记ID |
|
title |
varchar |
50 |
N |
Y |
笔记题目 |
|
keywords |
varchar |
150 |
N |
Y |
笔记关键字 |
|
desci |
varchar |
500 |
N |
Y |
笔记描述 |
|
pic |
varchar |
500 |
N |
Y |
笔记图片地址 |
|
content |
text |
0 |
N |
Y |
笔记详细内容 |
|
click |
mediumint |
9 |
N |
Y |
笔记点击量 |
|
time |
timestamp |
50 |
N |
Y |
笔记发表日期 |
栏目表(catalog)如表3.17所示,存储栏目信息
表3.17栏目表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
mediumint |
9 |
Y |
N |
栏目ID |
|
name |
varchar |
30 |
N |
N |
栏目名称 |
|
keywords |
varchar |
150 |
N |
N |
栏目关键词 |
|
desc |
text |
0 |
N |
N |
栏目描述 |
|
type |
tinyint |
150 |
N |
N |
栏目类型0:列表;1:留言 |
评论表(comment) 如表3.18所示,存储笔记评论信息
表3.18评论表
|
字段名称 |
数据类型 |
大小 |
主键 |
是否空 |
说明 |
|
id |
bigint |
20 |
Y |
N |
评论ID |
|
article_id |
bigint |
20 |
N |
N |
笔记ID |
|
content |
text |
0 |
N |
Y |
评论内容 |
|
date |
timestamp |
0 |
N |
Y |
评论日期 |
|
name |
varchar |
10 |
N |
Y |
留言者名称 |
|
|
varchar |
30 |
N |
Y |
留言者邮箱 |
3.2.3.基表设计
1、管理员表,如图3.19所示:
图3.19管理员表设计结果
2、管理员登录日志表,如图3.20所示:
图3.20管理员登录日志表设计结果
3、文章表,如图3.21所示:
图3.21文章表结果
4、栏目表,如图3.22所示:
图3.22栏目表设计结果
5、评论表,如图3.23所示:
图3.23评论表设计结果
4.软件实现
4.1.编码设计风格
1、命名时必须全部使用英文小写字母,禁止使用“下划线”等字符。
2、类名以及接口名的第一个字母应该大写。若类名中包含多个单词,则其中的每个内部单词的第一个字母都应该大写。
3、方法、字段(成员变量)名以及对象引用名称等开头应该使用小写字母,如果名称中包含多个单词,则其中的每个单词的第一个字母都要大写。
4、使用java+数据库+spring等技术,使代码整体结构清晰,便于各种操作。
5、spring特点: spring可以实现java模块化开发,贯穿表现层,业务层,逻辑层,实现了各个层之间的解耦合关系。
4.2.详细实现过程及代码
4.2.1.管理员登录层
当管理员的输入账号密码时,客户端将管理员的输入账号密码输送到数据库进行比较。如果可以在数据库中可以找到与传入的帐户和密码相同的数据,则登录成功,进入到管理员界面。否则,登录失败,无法进入管理员界面。如图4.1所示。
4.2.1.1.1.1.1.1.1.
4.1登录流程设计图
代码实现:
package com.blog.web;
import com.blog.domain.Admin;
import com.blog.domain.AdminLoginLog;
import com.blog.service.impl.AdminLoginLogServiceImpl;
import com.blog.service.impl.AdminServiceImpl;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
@Controller
public class LoginController {
@Autowired
AdminServiceImpl adminService;
@Autowired
AdminLoginLogServiceImpl adminLoginLogService;
@RequestMapping(value = {"/admin/index","/admin","/admin/login"})
public String toIndex(HttpServletRequest request) {
return "admin/login";
}
// 0:用户不存在 1:密码错误 2:登陆成功
@RequestMapping(value = "/api/loginCheck", method = RequestMethod.POST)
public @ResponseBody Object loginCheck(HttpServletRequest request,HttpServletResponse httpServletResponse) {
int id=Integer.parseInt(request.getParameter("id"));
String passwd = request.getParameter("password");
HashMap<String, String> res = new HashMap<String, String>();
if(adminService.getById(id)==null){
res.put("stateCode", "0");
}
else if(!adminService.getById(id).getPassword().equals(passwd)){
res.put("stateCode", "1");
}else {
String ip=request.getRemoteAddr();
AdminLoginLog adminLoginLog=new AdminLoginLog();
adminLoginLog.setAdminId(id);
adminLoginLog.setDate(new Date());
adminLoginLog.setIp(ip);
int log=adminLoginLogService.insert(adminLoginLog);
Cookie cookie = new Cookie("userId",""+id);
cookie.setMaxAge(3600*24);
httpServletResponse.addCookie(cookie);
request.getSession().setAttribute("admin",adminService.getById(id));
res.put("stateCode", "2");
}
return res;
}
@RequestMapping(value = {"/admin/logout"})
public String logout(HttpServletRequest request,HttpServletResponse response) {
request.getSession().removeAttribute("admin");
return "redirect:/admin";
}
}
package com.blog.service;
import com.blog.domain.AdminLoginLog;
import java.util.List;
public interface AdminLoginLogService {
List<AdminLoginLog> selectRencent(Integer adminId);
int insert(AdminLoginLog adminLoginLog);
int selectCountByAdminId(int adminId);
}
package com.blog.service.impl;
import com.blog.dao.AdminLoginLogDao;
import com.blog.domain.AdminLoginLog;
import com.blog.service.AdminLoginLogService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class AdminLoginLogServiceImpl implements AdminLoginLogService{
@Autowired
public AdminLoginLogDao adminLoginLogDao;
public List<AdminLoginLog> selectRencent(Integer adminId) {
return adminLoginLogDao.selectRencent(adminId);
}
public int insert(AdminLoginLog adminLoginLog) {
return adminLoginLogDao.insert(adminLoginLog);
}
public int selectCountByAdminId(int adminId) {
return adminLoginLogDao.selectCountByAdminId(adminId);
}
}
package com.blog.dao;
import com.blog.domain.AdminLoginLog;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface AdminLoginLogDao {
int deleteByPrimaryKey(Long id);
int insert(AdminLoginLog record);
int insertSelective(AdminLoginLog record);
AdminLoginLog selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(AdminLoginLog record);
int updateByPrimaryKey(AdminLoginLog record);
List<AdminLoginLog> queryAll();
List<AdminLoginLog> selectRencent(Integer adminId);
int selectCountByAdminId(Integer adminId);
}
4.2.2.笔记管理层
笔记管理层包括管理员对笔记的新建、编辑、查看详情、评论管理、修改、搜索等功能的实现
代码实现:
package com.blog.web;
import com.blog.domain.Article;
import com.blog.domain.Comment;
import com.blog.service.impl.ArticleServiceImpl;
import com.blog.service.impl.CommentServiceImpl;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
@Controller
public class ArticleController {
@Autowired
ArticleServiceImpl articleService;
@Autowired
public CommentServiceImpl commentService;
@RequestMapping("/article")
public ModelAndView detail(HttpServletRequest request){
int id=Integer.parseInt(request.getParameter("id"));
List<Comment> comments=commentService.allComments(id,0,10);
Article article=articleService.selectById(id);
Article lastArticle=articleService.selectLastArticle(id);
Article nextArticle=articleService.selectNextArticle(id);
Integer clickNum=article.getClick();
article.setClick(clickNum+1);
articleService.updateArticle(article);
ModelAndView modelAndView=new ModelAndView("detail");
modelAndView.addObject("article",article);
modelAndView.addObject("comments",comments);
modelAndView.addObject("lastArticle",lastArticle);
modelAndView.addObject("nextArticle",nextArticle);
return modelAndView;
}
@RequestMapping("/admin/article/detail")
public ModelAndView adminArticleDetail(HttpServletRequest request){
int id=Integer.parseInt(request.getParameter("id"));
Article article=articleService.selectById(id);
ModelAndView modelAndView=new ModelAndView("/admin/article_detail");
modelAndView.addObject("article",article);
return modelAndView;
}
@RequestMapping("/admin/article/comment")
public ModelAndView adminArticleComment(HttpServletRequest request){
int id=Integer.parseInt(request.getParameter("id"));
List<Comment> comments=commentService.allComments(id,0,10);
ModelAndView modelAndView=new ModelAndView("/admin/comment_list");
modelAndView.addObject("comments",comments);
return modelAndView;
}
@RequestMapping("/admin/article/list")
public ModelAndView articleList(@RequestParam(required=true,defaultValue="1") Integer page, @RequestParam(required=false,defaultValue="10") Integer pageSize){
PageHelper.startPage(page, pageSize);
List<Article> articles=articleService.queryAll();
PageInfo<Article> pageInfo=new PageInfo<Article>(articles);
ModelAndView modelAndView=new ModelAndView("/admin/article_list");
modelAndView.addObject("articles",articles);
modelAndView.addObject("pageInfo",pageInfo);
return modelAndView;
}
@RequestMapping("/admin/article/add")
public ModelAndView articleAdd(){
ModelAndView modelAndView=new ModelAndView("/admin/article_add");
return modelAndView;
}
@RequestMapping("/admin/article/add/do")
public String articleAddDo(HttpServletRequest request,RedirectAttributes redirectAttributes){
Article article=new Article();
article.setTitle(request.getParameter("title"));
article.setCatalogId(Integer.parseInt(request.getParameter("catalogId")));
article.setKeywords(request.getParameter("keywords"));
article.setdesci(request.getParameter("desci"));
article.setContent(request.getParameter("content"));
article.setTime(new Date());
if (articleService.insert(article)){
redirectAttributes.addFlashAttribute("succ", "发表文章成功!");
return "redirect:/admin/article/add";
}else {
redirectAttributes.addFlashAttribute("error", "发表文章失败!");
return "redirect:/admin/article/add";
}
}
@RequestMapping(value = "/admin/article/search")
public ModelAndView articleSearch(HttpServletRequest request){
String word=request.getParameter("word");
List<Article> articles=articleService.selectByWord(word);
ModelAndView modelAndView=new ModelAndView("/admin/article_list");
modelAndView.addObject("articles",articles);
return modelAndView;
}
@RequestMapping(value = "/admin/article/edit")
public ModelAndView articleEdit(HttpServletRequest request){
int id=Integer.parseInt(request.getParameter("id"));
Article article=articleService.selectById(id);
ModelAndView modelAndView=new ModelAndView("/admin/article_edit");
modelAndView.addObject("article",article);
return modelAndView;
}
@RequestMapping(value = "/admin/article/edit/do")
public ModelAndView articleEditDo(HttpServletRequest request){
Article article=new Article();
article.setId(Integer.parseInt(request.getParameter("id")));
article.setTitle(request.getParameter("title"));
article.setCatalogId(Integer.parseInt(request.getParameter("catalogId")));
article.setKeywords(request.getParameter("keywords"));
article.setdesci(request.getParameter("desci"));
article.setContent(request.getParameter("content"));
ModelAndView modelAndView=new ModelAndView("/admin/article_edit");
if (articleService.updateArticle(article)){
modelAndView.addObject("succ", "修改文章成功!");
}else {
modelAndView.addObject("error", "修改文章失败!");
}
return modelAndView;
}
@RequestMapping(value = "/api/article/del", method = RequestMethod.POST)
public @ResponseBody Object loginCheck(HttpServletRequest request) {
int id=Integer.parseInt(request.getParameter("id"));
int result=articleService.deleteById(id);
HashMap<String, String> res = new HashMap<String, String>();
if (result==1){
res.put("stateCode", "1");
}else {
res.put("stateCode", "0");
}
return res;
}
}
package com.blog.service;
import com.blog.domain.Article;
import java.util.ArrayList;
import java.util.List;
public interface ArticleService {
Article selectById (Integer id);
Article selectLastArticle (Integer id);
Article selectNextArticle (Integer id);
List<Article> queryAll();
int countAllNum();
boolean updateArticle(Article article);
int deleteById(Integer id);
int selectCount();
List<Article> selectByWord(String word);
boolean insert(Article article);
}
package com.blog.service.impl;
import com.blog.dao.ArticleDao;
import com.blog.domain.Article;
import com.blog.service.ArticleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
@Service
public class ArticleServiceImpl implements ArticleService{
@Autowired
public ArticleDao articleDao;
public Article selectById(Integer id) {
return articleDao.selectByPrimaryKey(id);
}
public List<Article> queryAll() {
return articleDao.queryAll();
}
public int countAllNum() {
return articleDao.countAllNum();
}
public boolean updateArticle(Article article) {
return articleDao.updateByPrimaryKeySelective(article)>0;
}
public int deleteById(Integer id) {
return articleDao.deleteByPrimaryKey(id);
}
public int selectCount() {
return articleDao.countAllNum();
}
public List<Article> selectByWord(String word) {
return articleDao.selectByWord(word);
}
public boolean insert(Article article) {
return articleDao.insert(article)>0;
}
public Article selectLastArticle(Integer id) {
return articleDao.selectLastArticle(id);
}
public Article selectNextArticle(Integer id) {
return articleDao.selectNextArticle(id);
}
}
package com.blog.dao;
import com.blog.domain.Article;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface ArticleDao {
int deleteByPrimaryKey(Integer id);
int insert(Article record);
int insertSelective(Article record);
Article selectByPrimaryKey(Integer id);
Article selectLastArticle(Integer id);
Article selectNextArticle(Integer id);
int updateByPrimaryKeySelective(Article record);
int updateByPrimaryKeyWithBLOBs(Article record);
int updateByPrimaryKey(Article record);
int countAllNum();
List<Article> queryAll();
List<Article> selectByWord(String word);
}
4.2.3.评论层
评论层主要是通过输入相应的昵称、评论内容、email等信息进行评论。
代码实现:
package com.blog.web;
import com.blog.domain.Comment;
import com.blog.service.impl.CommentServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
@Controller
public class CommentController {
@Autowired
public CommentServiceImpl commentService;
@RequestMapping(value = "/api/comment/add", method = RequestMethod.POST)
public @ResponseBody Object commentAdd(HttpServletRequest request) {
Comment comment=new Comment();
comment.setArticleId(Long.parseLong(request.getParameter("articleId")));
comment.setContent(request.getParameter("content"));
comment.setDate(new Date());
comment.setName(request.getParameter("name"));
comment.setEmail(request.getParameter("email"));
HashMap<String, String> res = new HashMap<String, String>();
if(commentService.insertComment(comment)>0){
res.put("stateCode", "1");
}else {
res.put("stateCode", "0");
}
return res;
}
@RequestMapping(value = "/api/comment/del", method = RequestMethod.POST)
public @ResponseBody Object commentDel(HttpServletRequest request) {
long id=Long.parseLong(request.getParameter("id"));
HashMap<String, String> res = new HashMap<String, String>();
if (commentService.delById(id)){
res.put("stateCode", "1");
}else {
res.put("stateCode", "0");
}
return res;
}
}
package com.blog.service;
import com.blog.domain.Comment;
import java.util.List;
public interface CommentService {
List<Comment> allComments(int article_id, int offset , int limit);
int insertComment(Comment comment);
int countAllNum();
boolean delById(Long id);
}
package com.blog.service.impl;
import com.blog.dao.CommentDao;
import com.blog.domain.Comment;
import com.blog.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class CommentServiceImpl implements CommentService {
@Autowired
public CommentDao commentDao;
public List<Comment> allComments(int article_id, int offset, int limit) {
return commentDao.queryAll(article_id,offset,limit);
}
public int insertComment(Comment comment) {
return commentDao.insert(comment);
}
public int countAllNum() {
return commentDao.countAllNum();
}
public boolean delById(Long id) {
return commentDao.deleteByPrimaryKey(id)>0;
}
}
package com.blog.dao;
import com.blog.domain.Article;
import com.blog.domain.Comment;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface CommentDao {
int deleteByPrimaryKey(Long id);
int insert(Comment record);
int insertSelective(Comment record);
Comment selectByPrimaryKey(Long id);
int updateByPrimaryKeySelective(Comment record);
int updateByPrimaryKeyWithBLOBs(Comment record);
int updateByPrimaryKey(Comment record);
int countAllNum();
List<Comment> queryAll(@Param("article_id") int article_id,@Param("offset") int offset, @Param("limit") int limit);
}
5.软件测试
软件测试主要是用来对一个过程的描述。软件测试是指在一定条件下运行程序来检测程序错误,测量和评估软件质量及其是否符合设计要求的过程。
5.1.测试目标
测试是在用户使用软件之前进行预先干预,编写多个测试用例尽可能多的测试发现软件中可能存在的错误,从而进一步保证软件的质量。软件只有经过再经过测试后才可以交付给用户。系统测试必须在个人笔记管理系统正式使用之前做,对于测试中发现的问题要及时做出修改处理,保证系统能够准确的供给用户。为了保证程序测试的效果和质量,将进行系统测试,测试将通过以下步骤进行。
5.2.测试具体内容
1.系统数据测试:主要测试每个模块内以及各个模块之间的数据传递等各种处理是否正确以及每个模块的功能是否正确。
2.系统数据库测试:主要测试系统数据库各个表之间数据传递,数据库表之间建立的主外键关系是否正确,数据库里的数据与实际录入的数据操作是否一致,是否存在不符合逻辑的数据情况。
3.系统整体性能测试:主要是针对系统的运行速度,运行稳定性,以及系统的操作的流畅性等方面进行检查。
5.3.软件代码测试
5.3.1.源代码一般性检查
1、命名规范检查
检查变量、函数、对象等的命名是否能见名知意,是否符合命名规范。项目源代码符合公约的要求。
2、注释检查
检查过程中的注释是否合理,是否简洁明了。
3、接口检查
检查外部接口比如数据库接口等是否满足要求,各代码模块使用的接口模式是否一致,具体的外部接口协议是否符合标准功能格式。
4、数据类型检查
源代码中涉及的数据类型是否符合要求,防止产生较大的误差,从而影响结果。
5.3.2.软件一致性检查
1、编译检查
确保提交的源代码为正确的源代码,编译无错误。
2、运行模块检查
确认之前项目在新的环境下准确无误地运行成功。
5.4.软件系统测试
5.4.1.界面(外观)测试
验证游客界面和管理员界面样式是否简洁明了、文本是否正确、页面是否美观、文本与图像的结合、操作是否正确等。确保游客界面和管理员界面符合企业或行业标准。
5.4.2.可用性测试
测试不同角色操作是否都简单快捷,每个角色的使用界面是否都很友好。
5.4.3.功能测试
输入正确数据后跳转到正确页面,对异常输入的数据会出现提示。对正确操作可以做出正确响应
5.4.4.稳定性(强度)测试
测试系统的能力最高实际限额。多个用户对系统进行访问,查看是否会出现运行不起来的现象,会不会出现数据错误、数据乱码。
5.4.5.逻辑性测试
根据自己编码时的逻辑,理顺整个系统的思路,测试系统中的数据,无论是正确的数据还是错误的数据都需要录入进行测试,看是否会出现错误。
5.5.单元测试
单位测试是一种检验和确认一个最小的可测试的单元,用于检验一个很简单、很清楚的程序,以确保它能够达到需要的功能。以管理员新建笔记功能为例的测试,如下表5.1所示:
表5.1功能测试用例
|
模块名称 |
测试用例 |
预期结果 |
实际结果 |
是否通过 |
|
新建笔记模块 |
输入正确的各部分笔记内容,点击发布。 |
弹出成功提示,提示发布成功 |
弹出成功提示,提示发布成功 |
通过 |
|
新建笔记模块 |
发布空内容 |
管理员查看笔记无内容 |
管理员查看笔记无内容 |
通过 |
5.6.回归测试
对于所实现功能的测试,是指该功能已经通过了一轮或多轮测试,并使用回归测试来确保这些功能的完整性。
经过如上测试后,宣布测试结果合格。



评论