天天看點

java 評論回複_評論回複功能設計

以評論為主的顯示模式,類似于下面的CSDN的評論顯示模式

java 評論回複_評論回複功能設計

最終效果圖

java 評論回複_評論回複功能設計

效果圖

将評論拆分為評論表和回複表,評論挂在各種主題下面,而回複挂在評論下面

我是采用的Jpa建表,是以隻需要把實體對象寫好就行

java 評論回複_評論回複功能設計

評論表

java 評論回複_評論回複功能設計

回複表

先上項目結構圖

java 評論回複_評論回複功能設計

項目結構圖

說一下我的思路

1.建立倆張表,回複表回複的id分為回複評論還是回複,用一個int标志判斷。

2.想像樹狀那樣顯示出來,這裡就采取連結清單的形式存儲,一條評論下可能有多人回複,是以存儲下一個對象我們使用List來存儲,開始的List初始化為private List replays = new ArrayList<>();不然replays.add()的時候會報空指針.

3.因為評論和回複是分開建表的,是以我們還需要單獨設定一個評論節點,分别對應上面項目結構圖的TopicNode和ReplayNode

4.插傳入連結表和周遊連結清單都是采用遞歸方式,有更好的方式歡迎指教。

5.thymeleaf寫遞歸方式和java一樣的思路,就是改變了文法而已

每個檔案源碼和注釋

Topic

package com.wg.springdemo.model;

import javax.persistence.*;

@Entity

@Table(name = "topic")

public class Topic {

@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE)

private Long tid;//主鍵ID

private Long uid;//使用者ID

@Column(length = 50)

private String uname;//使用者名

@Column(length = 255)

private String uheadurl;//使用者頭像

@Column(length = 800)

private String tcontent;//評論内容

@Column(length = 20)

private String ttime;//評論時間

public Topic() {

}

public Topic(Long uid, String uname, String uheadurl, String tcontent, String ttime) {

this.uid = uid;

this.uname = uname;

this.uheadurl = uheadurl;

this.tcontent = tcontent;

this.ttime = ttime;

}

public Long getTid() {

return tid;

}

public void setTid(Long tid) {

this.tid = tid;

}

public Long getUid() {

return uid;

}

public void setUid(Long uid) {

this.uid = uid;

}

public String getUname() {

return uname;

}

public void setUname(String uname) {

this.uname = uname;

}

public String getUheadurl() {

return uheadurl;

}

public void setUheadurl(String uheadurl) {

this.uheadurl = uheadurl;

}

public String getTcontent() {

return tcontent;

}

public void setTcontent(String tcontent) {

this.tcontent = tcontent;

}

public String getTtime() {

return ttime;

}

public void setTtime(String ttime) {

this.ttime = ttime;

}

@Override

public String toString() {

return "Topic{" +

"tid=" + tid +

", uid=" + uid +

", uname='" + uname + '\'' +

", uheadurl='" + uheadurl + '\'' +

", tcontent='" + tcontent + '\'' +

", ttime='" + ttime + '\'' +

'}';

}

}

Replay

package com.wg.springdemo.model;

import javax.persistence.*;

@Entity

@Table(name = "replay")

public class Replay {

@Id

@GeneratedValue(strategy = GenerationType.SEQUENCE)

private Long rid;

private Long torrid;//評論id或者回複id 就是有可能是回複評論,也可能是給回複的回複

private int torr;//用來判斷上面的哪種情況:1表示回複評論 0表示回複回複

private Long uid;//使用者ID

private Long touid;//目标使用者id 給誰回複

@Column(length = 50)

private String uname;//使用者名

@Column(length = 50)

private String touname;//目标使用者名

@Column(length = 255)

private String uheadurl;//使用者頭像

@Column(length = 800)

private String rcontent;//回複内容

@Column(length = 20)

private String rtime;//回複時間

public Replay() {

}

public Replay(Long torrid, int torr, Long uid, Long touid, String uname, String touname, String uheadurl, String rcontent, String rtime) {

this.torrid = torrid;

this.torr = torr;

this.uid = uid;

this.touid = touid;

this.uname = uname;

this.touname = touname;

this.uheadurl = uheadurl;

this.rcontent = rcontent;

this.rtime = rtime;

}

public Long getRid() {

return rid;

}

public void setRid(Long rid) {

this.rid = rid;

}

public Long getTorrid() {

return torrid;

}

public void setTorrid(Long torrid) {

this.torrid = torrid;

}

public int getTorr() {

return torr;

}

public void setTorr(int torr) {

this.torr = torr;

}

public Long getUid() {

return uid;

}

public void setUid(Long uid) {

this.uid = uid;

}

public Long getTouid() {

return touid;

}

public void setTouid(Long touid) {

this.touid = touid;

}

public String getUname() {

return uname;

}

public void setUname(String uname) {

this.uname = uname;

}

public String getTouname() {

return touname;

}

public void setTouname(String touname) {

this.touname = touname;

}

public String getUheadurl() {

return uheadurl;

}

public void setUheadurl(String uheadurl) {

this.uheadurl = uheadurl;

}

public String getRcontent() {

return rcontent;

}

public void setRcontent(String rcontent) {

this.rcontent = rcontent;

}

public String getRtime() {

return rtime;

}

public void setRtime(String rtime) {

this.rtime = rtime;

}

@Override

public String toString() {

return "Replay{" +

"rid=" + rid +

", torrid=" + torrid +

", torr=" + torr +

", uid=" + uid +

", touid=" + touid +

", uname='" + uname + '\'' +

", touname='" + touname + '\'' +

", uheadurl='" + uheadurl + '\'' +

", rcontent='" + rcontent + '\'' +

", rtime='" + rtime + '\'' +

'}';

}

}

TopicDao

package com.wg.springdemo.dao;

import com.wg.springdemo.model.Topic;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

@Repository

public interface TopicDao extends JpaRepository {

}

ReplayDao

package com.wg.springdemo.dao;

import com.wg.springdemo.model.Replay;

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.stereotype.Repository;

import java.util.List;

@Repository

public interface ReplayDao extends JpaRepository {

//找到所有對某評論的回複 或者對 某回複 的所有回複

List findByTorridAndTorr(Long torrid,int tr);

}

TopicService

package com.wg.springdemo.service;

import com.wg.springdemo.dao.TopicDao;

import com.wg.springdemo.model.Topic;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

@Service

public class TopicService {

@Autowired

TopicDao topicDao;

//存入一條評論

public Topic InsertOneTopic(Topic t){

return topicDao.save(t);

}

//查找所有評論

public List FindAllTopic(){

return topicDao.findAll();

}

}

ReplayService

package com.wg.springdemo.service;

import com.wg.springdemo.dao.ReplayDao;

import com.wg.springdemo.model.Replay;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import java.util.List;

@Service

public class ReplayService {

@Autowired

ReplayDao replayDao;

//插入一條回複

public Replay InsertOneReplay(Replay r){

return replayDao.save(r);

}

//找到對某個評論的所有回複

public List FindAllByTid(Long tid){

return replayDao.findByTorridAndTorr(tid,1);

}

//找到對某個回複的所有回複

public List FindAllByRid(Long rid){

return replayDao.findByTorridAndTorr(rid,0);

}

}

TopicNode

package com.wg.springdemo.util;

import com.wg.springdemo.model.Replay;

import com.wg.springdemo.model.Topic;

import java.util.ArrayList;

import java.util.List;

public class TopicNode {

private Topic topic;

private List replays = new ArrayList<>();

public TopicNode() {

}

public Topic getTopic() {

return topic;

}

public void setTopic(Topic topic) {

this.topic = topic;

}

public List getReplays() {

return replays;

}

public void setReplays(List replays) {

this.replays = replays;

}

}

ReplayNode

package com.wg.springdemo.util;

import com.wg.springdemo.model.Replay;

import java.util.ArrayList;

import java.util.List;

public class ReplayNode {

private Replay replay;

private List listreplay = new ArrayList<>();

public ReplayNode() {

}

public Replay getReplay() {

return replay;

}

public void setReplay(Replay replay) {

this.replay = replay;

}

public List getListreplay() {

return listreplay;

}

public void setListreplay(List listreplay) {

this.listreplay = listreplay;

}

}

java 評論回複_評論回複功能設計

添加測試資料

package com.wg.springdemo;

import com.wg.springdemo.model.Replay;

import com.wg.springdemo.model.Topic;

import com.wg.springdemo.service.ReplayService;

import com.wg.springdemo.service.TopicService;

import org.junit.Test;

import org.junit.runner.RunWith;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)

@SpringBootTest

public class SpringdemoApplicationTests {

@Autowired

ReplayService replayService;

@Autowired

TopicService topicService;

@Test

public void contextLoads() {

topicService.InsertOneTopic(new Topic( 1L,"小紅","1.jpg","這是第一個評論","2018-01-02"));

topicService.InsertOneTopic(new Topic( 2L,"小黃","1.jpg","這是第二個評論","2018-01-02"));

topicService.InsertOneTopic(new Topic( 3L,"小綠","1.jpg","這是第三個評論","2018-01-02"));

topicService.InsertOneTopic(new Topic( 4L,"小黑","1.jpg","這是第四個評論","2018-01-02"));

topicService.InsertOneTopic(new Topic( 1L,"小紅","1.jpg","這是第五個評論","2018-01-02"));

replayService.InsertOneReplay(new Replay(1L,1,2L,1L,"小黃","小紅","1.jpg","這是第一條回複","2018-01-02"));

replayService.InsertOneReplay(new Replay(1L,1,3L,1L,"小綠","小紅","1.jpg","這是第二條回複","2018-01-02"));

replayService.InsertOneReplay(new Replay(1L,0,4L,2L,"小黑","小黃","1.jpg","這是第一.一條回複","2018-01-02"));

replayService.InsertOneReplay(new Replay(3L,0,2L,4L,"小黃","小黑","1.jpg","這是第一.一.一條回複","2018-01-02"));

replayService.InsertOneReplay(new Replay(4L,0,4L,2L,"小黑","小黃","1.jpg","這是第一.一.一.一條回複","2018-01-02"));

replayService.InsertOneReplay(new Replay(4L,0,1L,1L,"小紅","小黃","1.jpg","這也是第一.一.一.一條回複","2018-01-02"));

replayService.InsertOneReplay(new Replay(3L,1,2L,3L,"小黃","小綠","1.jpg","這是第三條回複","2018-01-02"));

}

}

HomeController

package com.wg.springdemo.controller;

import com.wg.springdemo.model.Replay;

import com.wg.springdemo.model.Topic;

import com.wg.springdemo.service.ReplayService;

import com.wg.springdemo.service.TopicService;

import com.wg.springdemo.util.ReplayNode;

import com.wg.springdemo.util.TopicNode;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import java.util.ArrayList;

import java.util.List;

@Controller

public class HomeController {

@Autowired

ReplayService replayService;

@Autowired

TopicService topicService;

//插傳入連結表 參數分别代表需要待插入的節點list 和這些節點的父親是誰

public boolean AddReplayNode(List relists,ReplayNode freplay){

//為空就直接傳回

if(relists.size()==0)return false;

//挨個周遊list中的節點資訊,然後如果節點還有孩子就繼續遞歸

for(Replay re:relists){

ReplayNode newreplaynode = new ReplayNode();

newreplaynode.setReplay(re);

freplay.getListreplay().add(newreplaynode);

List replayList = new ArrayList<>();

replayList = replayService.FindAllByRid(re.getRid());

//有孩子就繼續遞歸,有沒有孩子這裡是統一進入遞歸才判斷,也可以來個if else

AddReplayNode(replayList,newreplaynode);

}

return false;

}

//展示出來 參數表示需要展示的節點list

public void ShowReplayNodes(List replayNodes){

if(replayNodes.size()==0)return;

for(ReplayNode temp: replayNodes){

System.out.println(temp.getReplay().toString());

ShowReplayNodes(temp.getListreplay());

}

}

@RequestMapping(value = "/", method = RequestMethod.GET)

public String getHomePostsByPage(Model model) {

List topics = new ArrayList<>();

topics = topicService.FindAllTopic();//得到所有評論

List topicNodes = new ArrayList<>();//裝下所有評論的List

for(Topic temp : topics){

TopicNode topicNode = new TopicNode();

topicNode.setTopic(temp);//把每個Topic變成TopicNode

Long tid = temp.getTid();

//找到是這個評論的所有回複

List thisreplays = new ArrayList<>();

thisreplays = replayService.FindAllByTid(tid);

//周遊每個第一層回複

for(Replay re:thisreplays){

ReplayNode replayNode = new ReplayNode();

replayNode.setReplay(re);

topicNode.getReplays().add(replayNode);

//得到回複的回複

List replayList = new ArrayList<>();

replayList = replayService.FindAllByRid(re.getRid());

//遞歸

AddReplayNode(replayList,replayNode);

}

topicNodes.add(topicNode);

}

//輸出

for(TopicNode tnode:topicNodes){

//得到評論

System.out.println(tnode.getTopic().toString());

ShowReplayNodes(tnode.getReplays());

}

model.addAttribute("topics",topicNodes);

return "index";

}

}

index.html

Index

java 評論回複_評論回複功能設計

小虎2018-01-02

這是留言内容

digui.html

java 評論回複_評論回複功能設計

小灰2018-01-02

回複 小虎 :這是回複内容

index.css

.onetopic{

margin: 10px 0;

}

.userhead{

width: 50px;

border: 1px solid #e8cfcf;

border-radius: 30px;

}

.name{

position: relative;

top: -18px;

}

.tr-time{

position: relative;

top: -18px;

left: 18px;

font-size: 12px;

}

.tr-content{

padding: 0 0 20px 0;

border-bottom: 1px solid #b1a5a5;

margin: 0;

margin-left:52px;

}

.onereplay{

margin: 10px 0 10px 40px;

}