Day47-SpringBoot仿牛客网社区开发03-开发社区首页

本文介绍了如何开发社区首页,展示前10个帖子,并实现分页功能,包括创建User实体类、DiscussPost类,以及相关Mapper接口和Service的实现。重点涵盖了数据库操作、分页查询和用户管理。
摘要由CSDN通过智能技术生成

开发流程

  • 1次请求的执行过程

分步实现

  • 开发社区首页,显示前10个帖子
  • 开发分页组件,分页显示所有的帖子
    在这里插入图片描述
  1. 创建User实体类,在com.nowcoder.community包下创建一个entity包,并创建一个User实体类:
package com.nowcoder.community.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import java.util.Date;

@Data
public class User {

    private Integer id;

    @NotEmpty(message = "用户名不能为空")
    @Length(min = 2, max = 16, message = "长度必须在2~16之间.")
    private String username;
    private String password;
    private String salt;

    @Email(message = "无效的邮箱")
    private String email;
    private Integer type;
    private Integer status;
    private String activationCode;
    private String headerUrl;
    private Date createTime;

    @TableField(exist = false)
    private UserMessageUnread unreadMessageCount;

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", salt='" + salt + '\'' +
                ", email='" + email + '\'' +
                ", type=" + type +
                ", status=" + status +
                ", activationCode='" + activationCode + '\'' +
                ", headerUrl='" + headerUrl + '\'' +
                ", createTime=" + createTime +
                '}';
    }

}

  1. 在entity包下创建DiscussPost类:
package com.nowcoder.community.entity;

import com.baomidou.mybatisplus.annotation.TableField;
import lombok.Data;
import lombok.EqualsAndHashCode;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.elasticsearch.annotations.Document;
import org.springframework.data.elasticsearch.annotations.Field;
import org.springframework.data.elasticsearch.annotations.FieldType;

import java.util.Date;

@Data
@EqualsAndHashCode(callSuper = true)
@Document(indexName = "discusspost")
public class DiscussPost extends LikeCountEntity{

    @Id
    private Integer id;

    @Field(type = FieldType.Integer)
    private Integer userId;

    // analyzer: 指定分词器为此字段进行分词, searchAnalyzer: 指定搜索时分词器为此字段分词.
    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String title;

    @Field(type = FieldType.Text, analyzer = "ik_max_word", searchAnalyzer = "ik_smart")
    private String content;

    @Field(type = FieldType.Integer)
    private Integer type;

    @Field(type = FieldType.Integer)
    private Integer status;

    @Field(type = FieldType.Date)
    private Date createTime;

    @Field(type = FieldType.Integer)
    private Integer commentCount;

    @Field(type = FieldType.Double)
    private double score;

    @Transient
    @TableField(exist = false)
    private long likeCount;

    @Override
    public String toString() {
        return "DiscussPost{" +
                "id=" + id +
                ", userId=" + userId +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", type=" + type +
                ", status=" + status +
                ", createTime=" + createTime +
                ", commentCount=" + commentCount +
                ", score=" + score +
                '}';
    }

}

  1. 创建一个DiscussPost类的Mapper接口,在dao包下创建一个命名为DiscussPostMapper的接口:
package com.nowcoder.community.dao;

import com.nowcoder.community.entity.DiscussPost;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Repository;

import java.util.List;

@Mapper
@Repository
public interface DiscussPostMapper {

    List<DiscussPost> selectDiscussPosts(int userId, int offset, int limit);

    // @Param注解用于给参数取别名,
    // 如果只有一个参数,并且在<if>里使用,则必须加别名.
    int selectDiscussPostRows(@Param("userId") int userId);

}

  1. 在resource文件目录中的mapper文件下创建一个discusspost-mapper.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.nowcoder.community.dao.DiscussPostMapper">

    <sql id="selectFields">
        id, user_id, title, content, type, status, create_time, comment_count, score
    </sql>

    <select id="selectDiscussPosts" resultType="DiscussPost">
        select <include refid="selectFields"></include>
        from discuss_post
        where status != 2
        <if test="userId!=0">
            and user_id = #{userId}
        </if>
        order by type desc, create_time desc
        limit #{offset}, #{limit}
    </select>

    <select id="selectDiscussPostRows" resultType="int">
        select count(id)
        from discuss_post
        where status != 2
        <if test="userId!=0">
            and user_id = #{userId}
        </if>
    </select>

</mapper>
  1. 在Service包下创建DiscussPostService类:
package com.nowcoder.community.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.nowcoder.community.controller.exception.PageNotFoundException;
import com.nowcoder.community.dao.EntityLikeDao;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.mapper.DiscussPostMapper;
import com.nowcoder.community.mapper.UserMapper;
import com.nowcoder.community.util.Constants;
import com.nowcoder.community.util.HostHolder;
import com.nowcoder.community.util.JsonBody;
import com.nowcoder.community.util.SensitiveWordFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@Service
public class DiscussPostService {
    @Autowired
    DiscussPostMapper discussPostMapper;

    @Autowired
    UserMapper userMapper;

    @Autowired
    EntityLikeDao entityLikeDao;

    @Autowired
    HostHolder hostHolder;

    public DiscussPost findPostById(int id) {
        return discussPostMapper.selectById(id);
    }

    /**
     * 增加指定id的贴子评论数
     */
    public void addCommentCountById(int id, int count) {
        discussPostMapper.addCommentCountById(id, count);
    }

    public List<DiscussPost> findDiscussPosts(int userId, int offset, int limit) {
        return discussPostMapper.findPageByUserId(userId, offset, limit);
    }

    public long countDiscussPosts() {
        return discussPostMapper.selectCount(new QueryWrapper<DiscussPost>(){
            {ne("status", 2);}
        });
    }

    public JsonBody addPost(DiscussPost post) {
        if (SensitiveWordFilter.hasSensitive(post.getTitle())) {
            return JsonBody.error("标题含敏感词, 发布失败.");
        }

        post.setStatus(0);
        post.setType(0);
        post.setContent(SensitiveWordFilter.filter(post.getContent()));
        discussPostMapper.insert(post);
        return JsonBody.ok("发布成功!");
    }

    public ModelAndView getPostDetailPage(int postId, Page commentPage) throws PageNotFoundException {
        ModelAndView ret = new ModelAndView("/site/discuss-detail");
        DiscussPost post = discussPostMapper.selectById(postId);
        if (post == null) {
            throw new PageNotFoundException("没有找到该帖子.");
        }
        // post其他信息处理
        post.setLikeCount(entityLikeDao.selectEntityLikeCount(Constants.ENTITY_TYPE_POST, postId));
        if (hostHolder.getUser() != null) {
            post.setLikeStatus(entityLikeDao.getLikeStatus(hostHolder.getUser().getId(), Constants.ENTITY_TYPE_POST, postId));
        }

        // 评论处理
        commentPage.setPath("/discuss/detail/" + postId);
        commentPage.setRows(post.getCommentCount() == null ? 0 : post.getCommentCount());

        // model构造
        User author = userMapper.selectById(post.getUserId());
        ret.addObject("post", post);
        ret.addObject("author", author);
        ret.addObject("page", commentPage);

        return ret;
    }
}

  1. 开发controller层,创建DiscussPostController类:
package com.nowcoder.community.controller;

import com.nowcoder.community.annotation.RestLoginRequire;
import com.nowcoder.community.controller.exception.PageNotFoundException;
import com.nowcoder.community.entity.Comment;
import com.nowcoder.community.entity.DiscussPost;
import com.nowcoder.community.entity.Page;
import com.nowcoder.community.entity.User;
import com.nowcoder.community.service.CommentService;
import com.nowcoder.community.service.DiscussPostService;
import com.nowcoder.community.util.Constants;
import com.nowcoder.community.util.HostHolder;
import com.nowcoder.community.util.JsonBody;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.ModelAndView;

import java.util.List;

@Slf4j
@Controller
@RequestMapping("discuss")
public class DiscussPostController {
    @Autowired
    DiscussPostService discussPostService;

    @Autowired
    CommentService commentService;

    @Autowired
    HostHolder hostHolder;

    @RestLoginRequire
    @ResponseBody
    @PostMapping("publish")
    public JsonBody addPost(String title, String content) {
        User user = hostHolder.getUser();
        DiscussPost post = new DiscussPost();
        post.setUserId(user.getId());
        post.setTitle(title);
        post.setContent(content);
        return discussPostService.addPost(post);
    }

    @GetMapping("detail/{discussPostId}")
    public ModelAndView getPostDetail(@PathVariable int discussPostId, Page commentPage) throws PageNotFoundException {
        log.debug("用户访问帖子{}的详细页面.", discussPostId);
        commentPage.setLimit(5);
        ModelAndView ret = discussPostService.getPostDetailPage(discussPostId, commentPage);
        if (commentPage.getRows() > 0) {
            List<Comment> comments = commentService.findCommentsByEntity(discussPostId, Constants.ENTITY_TYPE_POST, commentPage);
            ret.addObject("comments", comments);
        }
        return ret;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

阿杰杰杰のblog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值