Java微型博客系统——评论功能的实现

评论功能的实现与Article展示页的修改

本章主要实现了博客的评论功能的实现,包括增删改查等功能。并且,由于权限不同,之前将文章页面分为了两个页面。其实是没有必要的,这次修改将两个页面合二为一。

1.数据库的建立

评论主要应该包括评论的作者、评论的内容、评论所在的文章id
数据库结构如下:
在这里插入图片描述其中comment_id是自增的主键
article_id是与文章编号关联的外键(删改联动)

2.数据库对应的pojo

这里的int类型最好写成它的包装类Integer,不然可能会出现一些问题。
数据的命名是比较重要的,最好不要出现驼峰命名,而是用"_"来分开两个词。

package com.zhz.f.provider.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import tk.mybatis.mapper.annotation.KeySql;

import javax.persistence.Id;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class ArticleComments {
    @Id
    @KeySql(useGeneratedKeys = true)//自增键回填
    Integer comment_id;
    String comment_owner;
    String comment_contents;
    Integer article_id;

    public ArticleComments(String comment_owner, String comment_contents, int article_id) {
        this.comment_owner = comment_owner;
        this.comment_contents = comment_contents;
        this.article_id = article_id;
    }
}

3.server层和dao层的实现

这次采用了一个不同的顺序,首先设计好api的接口,实现可能需要的增删改查的功能。而不是像之前一样,等需要什么功能的时候再来写dao层。

MyData.java中增加的接口

//评论:
Boolean createAnArticleComment(String comment_owner, String comment_contents, Integer article_id);
Boolean deleteAnArticleComment(int comment_id);
Boolean updateAnArticleComment(int comment_id, String comment_contents);
Map<Integer, Map<String, String>> getAllCommentsByArticleID(int article_id);

*** 后续修改:之前因为嫌不好放在服务器上,不使用类传递数据而使用map套map的方法,现在感觉这个太垃圾所以又改了过来。***

//Map> getAllCommentsByArticleID(int article_id); 
ArrayList<CommonArticleComments> getAllCommentsByArticleID(int article_id);

这个CommonArticleComments放在common包下:
Java微型博客系统——评论功能的实现_第1张图片

package com.zhz.f.common.classes;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.io.Serializable;

@Data
@AllArgsConstructor
@NoArgsConstructor
// 需要传输的类必须支持序列化
public class CommonArticleComments implements Serializable {
    public Integer commentID;
    public String commentOwner;
    public String commentContent;
}

它们的实现:

@Override
public Boolean createAnArticleComment(String comment_owner, String comment_contents, Integer article_id) {
    commentsMapper.insert(new ArticleComments(comment_owner, comment_contents, article_id));
    return null;
}
@Override
public Boolean deleteAnArticleComment(int comment_id) {
    commentsMapper.deleteByPrimaryKey(comment_id);
    return null;
}
@Override
public Boolean updateAnArticleComment(int comment_id, String comment_contents) {
    commentsMapper.updateAnArticleComment(comment_id, comment_contents);
    return null;
}
/*@Override
public Map> getAllCommentsByArticleID(int article_id) {
    //用一个嵌套的map存数据返回。其实应该直接传一个类的数据是最好的,将类的定义放在comment里面。
    // 但是我不知道怎么将这种分布式的项目很好的去打包上传到服务器运行。为了之后可以在服务器上跑,这里就用了一个笨方法了。
    Map> result = new HashMap<>();
    List commentsIDs = commentsMapper.selectAllCommentsIDsByArticleID(article_id);
    for (Integer comment_id : commentsIDs) {
        //使用通用mapper的话这里传的必须是comment_id
        ArticleComments ac = commentsMapper.selectByPrimaryKey(comment_id);
        Map ccm = new HashMap<>();
        ccm.put(ac.getComment_owner(), ac.getComment_contents());
        result.put(comment_id, ccm);
    }
    return result;
    */
    @Override
    public ArrayList<CommonArticleComments> getAllCommentsByArticleID(int article_id) {
        List<Integer> commentsIDs = commentsMapper.selectAllCommentsIDsByArticleID(article_id);
        ArrayList<CommonArticleComments> result = new ArrayList<>();
        for (Integer comment_id : commentsIDs) {
            //使用通用mapper的话这里传的必须是comment_id
            ArticleComments ac = commentsMapper.selectByPrimaryKey(comment_id);
            result.add(new CommonArticleComments(ac.getComment_id(),ac.getComment_owner(),ac.getComment_co ntents()));
        }
        return result;
    }
}

dao层主要是调用了通用mapper的简单方法和自己写的一些方法。由于比较简单就不放上来

4.控制层和前端的联调

评论的功能应该是嵌入在文章页面的,所以需要修改之前的前端页面。
由于权限不同,之前将文章页面分为了两个页面。其实是没有必要的,可以加上一个thymeleaf的if语句判断即可。修改后并加上评论功能的article前端页面如下:
这里涉及到了很多的前后端的数据传输,看起来有些复杂,但其实很多都是一些判断条件,获得文章的各种信息和评论的各种信息和用户信息等。

article.html

DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8">
    <title th:text="${articleOwnerName}">的博文title>
    
    <div th:if="${articleOwnerAccount} eq ${userAccount}">
        <form action="/zhz/editArticle">
            <input type="text" name="articleTitle" th:value="${articleTitle}" hidden>
            <input type="submit" value="修改该文章">
        form>
        <form action="/zhz/deleteArticle">
            <input type="text" name="articleTitle" th:value="${articleTitle}" hidden>
            <input type="submit" value="删除该文章">
        form>
    div>
head>
<body>

<h2>
    <div th:text="${articleTitle}">div>
h2>
<h4>作者:<strong th:text="${articleOwnerName}"> strong>作者账号:<strong th:text="${articleOwnerAccount}">strong>h4>


<textarea name="newContent" rows="50" cols="80" th:utext="${content}" readonly>textarea>

<h3>看看大家的精彩评论吧h3>
<ol>
    <li th:each="ac:${articleComments}">
        <form action="/zhz/editAndDeleteArticleComments" method="post">
            <strong th:text="${ac.commentOwner}" th:colspan="10">strong><textarea name="articleCommentContents" th:text="${ac.commentContent}" style="overflow: visible"
                      readonly>textarea>
            <input name="articleCommentID" th:value="${ac.commentID}" hidden>
            <input name="articleTitle" th:value="${articleTitle}" hidden>
            <div th:if="${userAccount} eq ${ac.commentOwner}">
                <strong>如果需要修评论,则修改后点击提交strong><br/>
                <textarea name="newArticleCommentContents" th:text="${ac.commentContent}"
                          style="overflow: visible">textarea>
                
                <input name="articleID" th:value="${articleID}" hidden>
                <input type="submit" value="修改评论" name="editComment">
            div>
        form>
    li>
ol>

<h3>写下您的评论h3>
<form action="/zhz/writeArticleComments" method="post">
    <textarea name="writeArticleComments" placeholder="请在此输入您的精彩评论">textarea>
    <input name="articleTitle" th:value="${articleTitle}" hidden>
    <input name="articleOwnerAccount" th:value="${articleOwnerAccount}" hidden>
    
    <input name="articleID" th:value="${articleID}" hidden>
    <input type="submit" value="提交评论">
form>

body>
html>

ToArticleController :

package com.zhz.f.client.controller.articles;

import com.zhz.f.api.service.MyData;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Controller
public class ToArticleController {
    @DubboReference
    MyData myData;

    @RequestMapping("/zhz/toArticle")
    public String toArticle(HttpServletRequest request, HttpSession session, Model model) {
        String articleID = request.getParameter("articleID");
        if ("".equals(articleID)) articleID = null;
        String articleOwnerAccount = null;
        String userAccount = (String) session.getAttribute("userAccount");
        if (articleID != null) {
            //id不为空,说明是从public界面进来的
            articleOwnerAccount = myData.getUserAccountByArticleID(Integer.parseInt(articleID));
        } else {
            //id为空,说明是从用户主页进来的,直接获取本用户的用户账号
            articleOwnerAccount = (String) session.getAttribute("userAccount");
        }
        //获取文章信息
        String articleOwnerName = myData.getUserNameByAccount(articleOwnerAccount);
        String articleTitle = request.getParameter("articleTitle");
        String content = myData.getUserArticleByAccountAndArticleName(articleOwnerAccount, articleTitle);
        //获取评论信息
        Map<Integer, Map<String, String>> allComments = null;
        if (articleID != null) {//public
            allComments = myData.getAllCommentsByArticleID(Integer.parseInt(articleID));
        } else {//user
            allComments = myData.getAllCommentsByArticleID(myData.getArticleIDByAccountAndArticleName(articleOwnerAccount, articleTitle));
        }
        //获取评论信息
        ArrayList<CommonArticleComments> articleComments = new ArrayList<>();
        if (articleID != null) {//public
            articleComments = myData.getAllCommentsByArticleID(Integer.parseInt(articleID));
        } else {//user
            articleComments = myData.getAllCommentsByArticleID(myData.getArticleIDByAccountAndArticleName(articleOwnerAccount, articleTitle));
        }
        
        /*//读取数据,转化为ArticleComments类型。哎,要是直接传类多方便,真是自作自受
        List articleComments = new ArrayList<>();
        for (Integer cID : allComments.keySet()) {
            Map stringStringMap = allComments.get(cID);
            for (String cOwner : stringStringMap.keySet()) {
                String cContents = stringStringMap.get(cOwner);
                articleComments.add(new ArticleComments(cID,cOwner,cContents));
            }
        }*/

        //添加到显示
        model.addAttribute("articleComments",articleComments);
        model.addAttribute("articleOwnerAccount", articleOwnerAccount);
        model.addAttribute("articleOwnerName", articleOwnerName);
        model.addAttribute("userAccount", userAccount);
        model.addAttribute("articleTitle", articleTitle);
        model.addAttribute("content", content);
        model.addAttribute("articleID", articleID);

//        if (articleID != null) return "/articles/article";
        return "/articles/article";
    }
    /*@Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class ArticleComments{
        public int commentID;
        public String commentOwner;
        public String commentContent;
    }*/
}

EditAndDeleteArticleCommentsController

处理删除评论和修改评论的controller,本来想将删改两个功能放在两个controller里,但是前端遍历的时候两个按钮都在一个form表单中。不知道大佬们有没有什么方法可以将这两个功能分开。
虽然这样也挺好用的,但层次和功能清楚的代码还是更优质的。

package com.zhz.f.client.controller.articleComments;

import com.zhz.f.api.service.MyData;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;

@Controller
public class EditAndDeleteArticleCommentsController {
    @DubboReference
    MyData myData;
    @RequestMapping("/zhz/editAndDeleteArticleComments")
    public String editAndDeleteArticleComments(HttpServletRequest request){
        String deleteComment = request.getParameter("deleteComment");
        String editComment = request.getParameter("editComment");
        String articleCommentID = request.getParameter("articleCommentID");
        if ("删除评论".equals(deleteComment)){
            myData.deleteAnArticleComment(Integer.parseInt(articleCommentID));
        }else if ("修改评论".equals(editComment)){
            String newArticleCommentContents = request.getParameter("newArticleCommentContents");
            myData.updateAnArticleComment(Integer.parseInt(articleCommentID),newArticleCommentContents);
        }

        //主要需要输入articleID(如果有),articleTitle
        return "forward:/zhz/toArticle";
    }
}

WriteArticleCommentsController

主要实现读取前端数据和将读取到的评论写入数据库的功能。

package com.zhz.f.client.controller.articleComments;

import com.zhz.f.api.service.MyData;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

@Controller
public class WriteArticleCommentsController {
    @DubboReference
    MyData myData;
    @RequestMapping("/zhz/writeArticleComments")
    public String writeArticleComments(HttpServletRequest request, HttpSession session){
        String userAccount = (String) session.getAttribute("userAccount");
        String writeArticleComments = request.getParameter("writeArticleComments");
        String articleOwnerAccount = request.getParameter("articleOwnerAccount");
        String articleTitle = request.getParameter("articleTitle");
        int articleID = myData.getArticleIDByAccountAndArticleName(articleOwnerAccount, articleTitle);
        myData.createAnArticleComment(userAccount,writeArticleComments,articleID);
        return "forward:/zhz/toArticle";
    }

}

总结

至此就基本实现了评论的功能。
前端页面不是很美观,没有学javaScript和Ajax等前端的东西,做其前端还是很简陋的。

你可能感兴趣的:(数据库,java,html5)