Java评论功能案例怎么编写

wen java案例 29

本文目录导读:

Java评论功能案例怎么编写

  1. 数据库设计
  2. 实体类
  3. DAO层
  4. Service层
  5. Controller层
  6. 统一返回结果类
  7. 前端HTML示例
  8. 配置文件
  9. 功能特点

我来为您提供一个完整的Java评论功能案例,包含前后端实现。

数据库设计

CREATE TABLE `comment` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `content` text NOT NULL COMMENT '评论内容',
  `user_id` bigint(20) NOT NULL COMMENT '用户ID',
  `user_name` varchar(50) NOT NULL COMMENT '用户名称',
  `article_id` bigint(20) NOT NULL COMMENT '文章ID',
  `parent_id` bigint(20) DEFAULT NULL COMMENT '父评论ID',
  `reply_user_id` bigint(20) DEFAULT NULL COMMENT '回复用户ID',
  `reply_user_name` varchar(50) DEFAULT NULL COMMENT '回复用户名称',
  `likes` int(11) DEFAULT '0' COMMENT '点赞数',
  `status` tinyint(4) DEFAULT '1' COMMENT '状态:1正常 0删除',
  `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
  `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
  PRIMARY KEY (`id`),
  KEY `idx_article_id` (`article_id`),
  KEY `idx_user_id` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='评论表';

实体类

// Comment.java
package com.example.entity;
import lombok.Data;
import java.time.LocalDateTime;
import java.util.List;
@Data
public class Comment {
    private Long id;
    private String content;
    private Long userId;
    private String userName;
    private Long articleId;
    private Long parentId;
    private Long replyUserId;
    private String replyUserName;
    private Integer likes;
    private Integer status;
    private LocalDateTime createTime;
    private LocalDateTime updateTime;
    // 用于展示的子评论列表
    private List<Comment> children;
}

DAO层

// CommentMapper.java
package com.example.mapper;
import com.example.entity.Comment;
import org.apache.ibatis.annotations.*;
import java.util.List;
@Mapper
public interface CommentMapper {
    // 添加评论
    @Insert("INSERT INTO comment(content, user_id, user_name, article_id, parent_id, " +
            "reply_user_id, reply_user_name, likes, status, create_time, update_time) " +
            "VALUES(#{content}, #{userId}, #{userName}, #{articleId}, #{parentId}, " +
            "#{replyUserId}, #{replyUserName}, 0, 1, NOW(), NOW())")
    @Options(useGeneratedKeys = true, keyProperty = "id")
    int insert(Comment comment);
    // 根据文章ID查询父评论(顶级评论)
    @Select("SELECT * FROM comment WHERE article_id = #{articleId} AND parent_id IS NULL AND status = 1 " +
            "ORDER BY create_time DESC")
    List<Comment> findParentComments(Long articleId);
    // 根据父评论ID查询子评论
    @Select("SELECT * FROM comment WHERE parent_id = #{parentId} AND status = 1 " +
            "ORDER BY create_time ASC")
    List<Comment> findChildComments(Long parentId);
    // 删除评论(逻辑删除)
    @Update("UPDATE comment SET status = 0 WHERE id = #{id}")
    int delete(Long id);
    // 点赞
    @Update("UPDATE comment SET likes = likes + 1 WHERE id = #{id}")
    int likeComment(Long id);
}

Service层

// CommentService.java
package com.example.service;
import com.example.entity.Comment;
import com.example.mapper.CommentMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.ArrayList;
import java.util.List;
@Service
public class CommentService {
    @Autowired
    private CommentMapper commentMapper;
    // 添加评论
    @Transactional
    public Comment addComment(Comment comment) {
        commentMapper.insert(comment);
        return comment;
    }
    // 获取文章的评论列表(树形结构)
    public List<Comment> getCommentsByArticleId(Long articleId) {
        // 获取所有父评论
        List<Comment> parentComments = commentMapper.findParentComments(articleId);
        // 为每个父评论添加子评论
        for (Comment parent : parentComments) {
            List<Comment> children = commentMapper.findChildComments(parent.getId());
            parent.setChildren(children);
        }
        return parentComments;
    }
    // 删除评论
    @Transactional
    public boolean deleteComment(Long id) {
        // 逻辑删除评论
        commentMapper.delete(id);
        // 如果有子评论,也一并删除
        List<Comment> children = commentMapper.findChildComments(id);
        for (Comment child : children) {
            commentMapper.delete(child.getId());
        }
        return true;
    }
    // 点赞评论
    public boolean likeComment(Long id) {
        commentMapper.likeComment(id);
        return true;
    }
}

Controller层

// CommentController.java
package com.example.controller;
import com.example.common.Result;
import com.example.entity.Comment;
import com.example.service.CommentService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/api/comment")
public class CommentController {
    @Autowired
    private CommentService commentService;
    // 添加评论
    @PostMapping("/add")
    public Result addComment(@RequestBody Comment comment) {
        // 模拟用户信息(实际应从登录用户获取)
        comment.setUserId(1L);
        comment.setUserName("测试用户");
        Comment result = commentService.addComment(comment);
        return Result.success(result);
    }
    // 获取文章的评论
    @GetMapping("/list/{articleId}")
    public Result getComments(@PathVariable Long articleId) {
        List<Comment> comments = commentService.getCommentsByArticleId(articleId);
        return Result.success(comments);
    }
    // 删除评论
    @DeleteMapping("/delete/{id}")
    public Result deleteComment(@PathVariable Long id) {
        commentService.deleteComment(id);
        return Result.success();
    }
    // 点赞评论
    @PostMapping("/like/{id}")
    public Result likeComment(@PathVariable Long id) {
        commentService.likeComment(id);
        return Result.success();
    }
}

统一返回结果类

// Result.java
package com.example.common;
import lombok.Data;
@Data
public class Result<T> {
    private Integer code;
    private String message;
    private T data;
    public static <T> Result<T> success(T data) {
        Result<T> result = new Result<>();
        result.setCode(200);
        result.setMessage("success");
        result.setData(data);
        return result;
    }
    public static Result success() {
        return success(null);
    }
    public static <T> Result<T> error(String message) {
        Result<T> result = new Result<>();
        result.setCode(500);
        result.setMessage(message);
        return result;
    }
}

前端HTML示例

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">评论系统</title>
    <style>
        .comment {
            border: 1px solid #ddd;
            padding: 15px;
            margin-bottom: 10px;
            border-radius: 5px;
        }
        .comment-header {
            display: flex;
            justify-content: space-between;
            margin-bottom: 10px;
        }
        .comment-user {
            font-weight: bold;
            color: #333;
        }
        .comment-time {
            color: #999;
            font-size: 12px;
        }
        .comment-content {
            margin-bottom: 10px;
        }
        .comment-actions {
            display: flex;
            gap: 15px;
        }
        .comment-actions button {
            border: none;
            background: none;
            cursor: pointer;
            color: #666;
        }
        .comment-actions button:hover {
            color: #007bff;
        }
        .children {
            margin-left: 30px;
            margin-top: 10px;
        }
        .reply-form {
            margin-top: 10px;
        }
        .reply-form textarea {
            width: 100%;
            height: 60px;
            margin-bottom: 10px;
        }
    </style>
</head>
<body>
    <div class="container">
        <h2>文章评论</h2>
        <!-- 评论表单 -->
        <div class="comment-form">
            <textarea id="commentContent" placeholder="写下你的评论..." style="width:100%;height:80px;"></textarea>
            <button onclick="submitComment()">发表评论</button>
        </div>
        <!-- 评论列表 -->
        <div id="commentList" class="comment-list"></div>
    </div>
    <script>
        // 获取评论列表
        async function loadComments() {
            try {
                const response = await fetch('/api/comment/list/1'); // 文章ID为1
                const result = await response.json();
                if (result.code === 200) {
                    renderComments(result.data);
                }
            } catch (error) {
                console.error('加载评论失败:', error);
            }
        }
        // 渲染评论
        function renderComments(comments) {
            const commentList = document.getElementById('commentList');
            commentList.innerHTML = comments.map(comment => renderComment(comment)).join('');
        }
        // 渲染单个评论
        function renderComment(comment) {
            return `
                <div class="comment" id="comment-${comment.id}">
                    <div class="comment-header">
                        <span class="comment-user">${comment.userName}</span>
                        <span class="comment-time">${formatTime(comment.createTime)}</span>
                    </div>
                    <div class="comment-content">${comment.content}</div>
                    <div class="comment-actions">
                        <button onclick="likeComment(${comment.id})">👍 ${comment.likes || 0}</button>
                        <button onclick="replyComment(${comment.id}, '${comment.userName}')">回复</button>
                        <button onclick="deleteComment(${comment.id})">删除</button>
                    </div>
                    <!-- 子评论 -->
                    ${comment.children && comment.children.length > 0 ? `
                        <div class="children">
                            ${comment.children.map(child => renderComment(child)).join('')}
                        </div>
                    ` : ''}
                </div>
            `;
        }
        // 提交评论
        async function submitComment(parentId = null, replyUserId = null, replyUserName = null) {
            const content = document.getElementById('commentContent').value;
            if (!content.trim()) {
                alert('请输入评论内容');
                return;
            }
            try {
                const response = await fetch('/api/comment/add', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({
                        content: content,
                        articleId: 1,
                        parentId: parentId,
                        replyUserId: replyUserId,
                        replyUserName: replyUserName
                    })
                });
                const result = await response.json();
                if (result.code === 200) {
                    document.getElementById('commentContent').value = '';
                    loadComments();
                }
            } catch (error) {
                console.error('提交评论失败:', error);
            }
        }
        // 点赞评论
        async function likeComment(id) {
            try {
                const response = await fetch(`/api/comment/like/${id}`, {method: 'POST'});
                const result = await response.json();
                if (result.code === 200) {
                    loadComments();
                }
            } catch (error) {
                console.error('点赞失败:', error);
            }
        }
        // 删除评论
        async function deleteComment(id) {
            if (!confirm('确定删除此评论?')) return;
            try {
                const response = await fetch(`/api/comment/delete/${id}`, {method: 'DELETE'});
                const result = await response.json();
                if (result.code === 200) {
                    loadComments();
                }
            } catch (error) {
                console.error('删除失败:', error);
            }
        }
        // 格式化时间
        function formatTime(time) {
            const date = new Date(time);
            return date.toLocaleString('zh-CN');
        }
        // 初始化加载评论
        loadComments();
    </script>
</body>
</html>

配置文件

# application.yml
server:
  port: 8080
spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/comment_db?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
    username: root
    password: your_password
mybatis:
  configuration:
    map-underscore-to-camel-case: true
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

功能特点

  1. 支持嵌套评论:实现评论和回复的树形结构
  2. 评论点赞:支持对评论进行点赞
  3. 评论删除:逻辑删除,保留数据完整性
  4. 时间排序:父评论按时间倒序,子评论按时间正序
  5. 前端交互:完整的HTML+JavaScript实现

这个案例包含了评论功能的核心实现,您可以根据实际需求进行扩展,比如添加用户认证、评论审核、分页加载等功能。

抱歉,评论功能暂时关闭!