zoukankan      html  css  js  c++  java
  • 基于SSM框架的简单问答社区

    前言:学习了Spring、SpringMVC、MyBatis框架后,开发了一套简单的问答社区,前端采用Bootstrap开发框架。

    版本信息

    IDEA:2020.1.2

    JDK:14.0.1

    Maven:3.6.3

    Tomcat:9.0.36

    MySql:8.0.20

    Bootstrap:3.3.7

    JQuery:3.5.1

     

    本文目录

    一、需求分析

    1、社区功能

    2、数据表

    3、数据表关系

    二、功能实现

    1、用户注册、登录、注销

    2、提出问题、修改问题、删除问题

    3、对问题进行回答、修改回答、删除回答

    4、对回答进行评论、修改评论、删除评论

    5、用户关注(取消关注)用户、用户关注(取消关注)问题、用户赞同(取消赞同)回答

    三、代码介绍

    1、项目结果

    2、部分代码

    四、效果演示

    1、登录

    2、注册

    3、用户主页面

    4、提出问题

    5、查看所有问题

    6、根据条件查询问题

    7、问题及回答信息

    8、回答及评论信息

    9、用户信息

    10、个人资料

    11、关注的用户、粉丝、关注的问题、赞同的回答、提出的问题、做出的回答、做出的评论

    12、修改、删除问题,修改、删除回答

    五、代码/功能优化

    六、开发经验

    七、GitHub项目地址

     

    一、需求分析

    1、社区功能

    ①用户注册、登录、注销;

    ②提出问题、修改问题、删除问题;

    ③对问题进行回答、修改回答、删除回答;

    ④对回答进行评论、修改评论、删除评论;

    ⑤用户关注(取消关注)用户、用户关注(取消关注)问题,用户赞同(取消赞同)回答。

    2、数据表

    (1)用户表

    user用户表
    user_id 用户编号
    user_name 用户名
    user_nickname 用户昵称
    user_avatar 用户头像
    user_sex 用户性别
    user_email 用户邮箱
    user_password 用户密码
    user_register_time 用户注册时间
    user_last_login_time 用户最近一次登录的时间
    user_last_login_ip 用户最近一次登录的IP地址
    user_status 用户状态

    (2)问题表

    question问题表外键
    question_id 问题编号  
    question_user_id 问题的提问者用户编号(关联用户表) user表user_id
    question_title 问题标题  
    question_content 问题内容  
    question_view_count 问题浏览量  
    question_follow_count 问题关注量  
    question_answer_count 问题回答量  
    question_update_time 问题更新时间  
    question_create_time 问题创建时间  
    question_status 问题状态  

    (3)回答表

    answer回答表外键
    answer_id 回答编号  
    answer_user_id 回答的回答者用户编号(关联用户表) user表user_id
    answer_question_id 回答所对应的问题编号(关联问题表) question表question_id
    answer_content 回答内容  
    answer_view_count 回答浏览量  
    answer_agree_count 回答赞同量  
    answer_update_time 回答更新时间  
    answer_create_time 回答创建时间  
    answer_status 回答状态  

    (4)评论表

    comment评论表外键/备注
    comment_id 评论编号  
    comment_user_id 评论的评论者用户编号(关联用户表) user表user_id
    comment_answer_id 评论所对应的回答编号(关联回答表) answer表answer_id
    comment_last_id 评论上一条评论编号 为Null表示一级评论,否则为二级及以上评论(对评论的评论)
    comment_content 评论内容  
    comment_time 评论时间  

    comment_last_id本打算用作辨别回答下的一级评论(对回答的评论)和二级及以下评论(即对评论进行回复的评论),但感觉过于复杂,所有目前并未使用该字段

    (5)用户与用户关系表

    user_relation_user用户关注用户关系表外键
    from_user_id 发起用户编号 user表user_id
    to_user_id 关注用户编号 user表user_id

    (6)用户与问题关系表

    user_relation_question用户关注问题关系表外键
    from_user_id 发起用户编号 user表user_id
    to_question_id 关注问题编号 question表question_id

    (7)用户与回答关系表

    user_relation_answer用户与回答关系表外键
    from_user_id 发起用户编号 user表user_id
    to_answer_id 赞同回答编号 answer表answer_id

    3、数据表关系

    (1)user表、question表、answer表、comment表之间的关系

    (2)user表、question表、answer表、user_relation_user表、user_relation_question表、user_relation_answer表之间的关系

    (3)由于有外键约束

    ①当删除用户时,user_relation_user表、user_relation_question表、user_relation_answer表的该用户关系均会删除,question表、answer表、comment表也会删除该用户的问题、回答及评论;

    ②当删除问题时,user_relation_question表的用户关系会删除,question表、answer表也会删除问题及回答;

    ③当删除回答时,user_relation_answer表的用户关系会删除,answer表、comment表也会删除回答及评论。

    二、功能实现

    1、用户注册、登录、注销

    ①用户注册时,查找数据库中是否已经存在注册的用户名,如果不存在,则将用户填入的注册信息,以及设置当前时间为用户注册时间、最近一次登录时间,存入数据库;

    ②用户登录时,首先前端先进行限制数据的输入格式,密码与确认密码相同,进入后端查找数据库中是否存在该用户,不存在则显示用户名不存在。若存在该用户名,再将密码和数据库中密码进行匹配,匹配成功则登录成功,反之失败;

    ③用户登录后,可点击注销按钮,根据存入session域中的登录用户编号删除数据库中用户。

    注意:记录最近一次登录IP功能还未实现,user_last_login_ip一直默认为null。user_status用来判断用户状态或身份,比如1为普通用户,0为管理员,2为禁用等,目前未开通这些功能,一直默认user_status=1。

    2、提出问题、修改问题、删除问题

    ①提出问题,根据session域中的登录用户编号及输入的问题信息,以及设置当前时间为问题创建时间、更新时间,存入数据库;

    ②修改问题,根据问题编号查出数据库中的该问题信息,根据输入修改问题信息,以及设置当前时间为问题更新时间,再存入数据库;

    ③删除问题,根据问题编号删除数据库中的问题。

    3、对问题进行回答、修改回答、删除回答

    ①进行回答,根据登录用户编号、问题编号、输入的回答信息,以及设置当前时间为回答创建时间、更新时间,存入数据库;

    ②修改回答,根据回答编号查出数据库中的该回答信息,根据输入修改回答信息,以及设置当前时间为回答更新时间,再存入数据库;

    ③删除回答,根据回答编号删除数据库中的回答。

    4、对回答进行评论、修改评论、删除评论

    ①进行评论,根据登录用户编号、回答编号、输入的评论信息,以及设置当前时间为评论时间,存入数据库;

    ②修改评论,根据评论编号查出数据库中的该评论信息,根据输入修改评论信息,以及设置当前时间为评论时间,再存入数据库;

    ③删除评论,根据评论编号删除数据库中的评论。

    注意:评论时间及最新的评论时间,修改后立即更新时间,查看不到首次评论时间

    5、用户关注(取消关注)用户、用户关注(取消关注)问题,用户赞同(取消赞同)回答

    ①用户关注用户、问题,用户赞同回答,首先查询数据库中是否存在对应关系,如果有则提示关注(赞同)失败,如果没有则将关系存入数据库;

    ②用户取消关注用户、问题,用户取消赞同回答,首先查询数据库中是否存在对应关系,如果有则提示取消关注(赞同)成功,如果有则将数据库中的对应关系删除。

    三、代码介绍

    1、项目结构

    2、部分代码

    (1)实体类

    (2)dao层

    java

    xml

    (3)service层

    接口

    实现类

    (4)controller层

    (5)测试类

     

    (6)前端

    JavaScript

     

    HTML

    四、效果演示

    1、登录

    2、注册

    3、用户主页面

    4、提出问题

    5、查看所有问题

    6、根据条件查询问题

    7、问题及回答信息(点击所有问题或者查询问题得到的页面的问题标题链接)

    在页面可以关注、取消关注问题,仅展示关注问题

    ①点击关注,如果已经关注,弹出“您已经关注该问题,不能重复关注”,如果没关注,弹出“关注成功”

    ②点击取消关注,如果已经关注,弹出“取消关注成功”,如果没关注,弹出“您还未关注该问题,不可取消关注”

    关注成功

    关注失败

    回答问题

    8、回答及评论信息(点击问题及回答信息页面的回答的详细内容链接)

    在此页面可以赞同及取消赞同该回答,其显示效果与关注与取消关注问题类型类似,故不展示

    评论回答

    9、用户信息(在问题及回答页面可点击问题标题右下侧名字链接,在回答及评论页面可点击回答或评论者的名字链接,进入用户详情信息页面)

    以上图的回答及评论页面为例,点击评论者周伯通

    在此页面可以关注或取消关注用户,与对问题和回答的操作同理,如果已经关注再点击关注、未关注点击取消关注会失败,未关注点击取消关注、已关注点击关注会失败

    10、个人资料(在用户页面可进入个人资料)

     

    此页面可点击修改用户信息

    输入框内容默认为用户信息,用户名不可更改,修改成功会返回个人页面

    注销用户会删除数据库内用户信息,直接退出到登录页面,此处不再展示

    11、用户页面的个人资料及退出登录按钮下有7个链接,分别可进入对应页面,此处仅挑部分页面展示

    ①关注的用户

    ②赞同的回答

    ③提出的问题

    ④做出的评论

    12、修改、删除问题,修改、删除回答,修改、删除评论

    可在用户页面“提出的问题”、“做出的回答”、“做出的评论”链接进入后的页面点击问题标题、回答内容、评论内容链接进入对应信息页面,然后对其进行修改、删除,此处仅以做出的回答举例

    ①用户页面,点击做出的回答链接

    ②进入回答页面,点击回答内容的链接

    ③进入回答详细页面,点击修改回答按钮

    ④进入修改回答页面,显示原回答内容

    ⑤修改回答内容

     ⑥点击确认修改

    ⑦点击返回回答页面

    ⑧点击刷新回答按钮,即可查看更新后的回答

    五、代码/功能优化

    1、question表可不需要question_answer_count字段,直接从answer表查询某问题下有多少回答即可,本项目因为多次需要查询问题时显示问题有多少评论量,故也作为一个属性。但因为question表内question_answer_count值在新增answer时加1,在删除answer时减1,此过程在service层实现,如果直接对数据库操作,question表的question_answer_count字段的值可能不正确;

    2、对问题、回答、评论等进行新增、更新、删除时有时会进入一个成功或失败提示页面,可以进行代码优化让其直接返回之前的信息页面,然后进行弹窗提示成功或失败信息,不需要单独进入一个提示页面;

    3、user表的user_avtar(用户头像)、user_last_login_ip(用户最近一次登录的IP地址)、user_status(用户状态)等字段并未使用,可以在后续开发中加上这些字段对应的功能;

    4、comment表中的comment_last_id字段表示评论的上一条评论编号,利用该字段可以实现对评论进行评论, 此目的主要是想实现回复功能,考虑到有些复杂本项目并未实现此功能

    六、开发经验

    在开发过程中,熟悉了许多过程,也在一些细节的地方浪费了许多时间,经过不断学习测试得出了一些经验,现挑一些印象深刻的进行归纳

    1、Dao层的类的方法传入参数为多个时,需要用到@Parma

    比如对user_relation_user表进行新增某用户关注某用户时,对应的UserRelationDao的类的方法为

    1 void saveUserFollowUser(Integer from_user_id,Integer to_user_id);

    UserRelationMapper.xml对应的xml语句

    1 <!-- 新增某用户关注某用户 -->
    2 <insert id="saveUserFollowUser" parameterType="java.lang.Integer" >
    3     INSERT INTO user_relation_user (from_user_id,to_user_id)
    4     VALUES (#{from_user_id},#{to_user_id})
    5 </insert>

    此时会报错,因为找不到from_user_id与to_user_id

    此时需要用到@Parma,修改后的UserRelationDao的类的方法为

    1 void saveUserFollowUser(@Param("from_user_id") Integer from_user_id,@Param("to_user_id") Integer to_user_id);

    2、JSP页面发送url请求时要用<%=path%>加上后续路径(JSP头部加上<% String path = request.getContextPath();%>)

    此处的内容关于JSP文件的绝对路径与相对路径,相关介绍网上已经很详细了

    如在用户页面查看所有问题

    1  <a href="Question/DisplayAllQuestionList"><button type="button" class="btn btn-success btn-lg" style=" 150px;">查看所有问题</button></a>

    对应的Controller类的方法为

     1 /**
     2  * 表现层 问题
     3  */
     4 @Controller
     5 @RequestMapping(value = "/Question")
     6 public class QuestionController {
     7     
     8     ······
     9     
    10     /**
    11     * 进入所有问题列表页面
    12     * @param model
    13     * @return
    14     */
    15     @RequestMapping(value = "/DisplayAllQuestionList")
    16     public String DisplayAllQuestionList(Model model) {
    17     ......
    18     }   
    19     
    20     ······
    21 }

    此时的请求可能会出错,我在运行过程中出现了404的问题,如图所示

    此时修改为如下方式即可

    1 <% String path = request.getContextPath();%>
    2 
    3 ......
    4 
    5 <a href="<%=path%>/Question/DisplayAllQuestionList"><button type="button" class="btn btn-success btn-lg" style=" 150px;">查看所有问题</button></a>
    6 ·····

    3、在JSP页面显示时间的格式问题

    如果在java中用java.util.Date接收MySQL中的datetime,然后直接在JSP页面显示,会输出以下格式

    此时的代码为

    1 ······
    2 <td>
    3     <p>${question.question_create_time}</p>
    4 </td>
    5 ······

    使用Jstl语句的格式化输出

    1 <%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt" %>
    2     
    3     ······
    4     
    5 <td>
    6     <fmt:formatDate value="${question.question_create_time}" pattern="yyyy-MM-dd HH:mm:ss"/>
    7 </td>
    8     
    9     ······

    此时会输出以下格式

    4、在之前发表过的随笔有过以下总结

    (1)@Controller类的方法如何解析ajax请求发送的请求体中的多个参数

    https://www.cnblogs.com/huskysir/p/13295631.html

    (2)关于在JSP页面识别不了EL表达式的情况

    https://www.cnblogs.com/huskysir/p/13283569.html

    (3)JSP页面中同时遍历多个List集合

    https://www.cnblogs.com/huskysir/p/13282191.html

    (4)如何从默认的index.jsp页面跳转到其他页面

    https://www.cnblogs.com/huskysir/p/13273734.html

    (5)SSM前后端信息交互

    https://www.cnblogs.com/huskysir/p/13308418.html

     七、GitHub项目地址

    https://github.com/HuskySir/JAVA/tree/master/QuestionPlatform

  • 相关阅读:
    NYOJ 625 笨蛋的难题(二)
    NYOJ 102 次方求模
    ZJU Least Common Multiple
    ZJUOJ 1073 Round and Round We Go
    NYOJ 709 异形卵
    HDU 1279 验证角谷猜想
    BNUOJ 1015 信息战(一)——加密程序
    HDU 1202 The calculation of GPA
    "蓝桥杯“基础练习:字母图形
    "蓝桥杯“基础练习:数列特征
  • 原文地址:https://www.cnblogs.com/huskysir/p/13308511.html
Copyright © 2011-2022 走看看