开发流程
分步实现
开发社区首页,显示前10个帖子 开发分页组件,分页显示所有的帖子
创建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 +
'}' ;
}
}
在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;
@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 +
'}' ;
}
}
创建一个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) ;
int selectDiscussPostRows ( @Param ( "userId" ) int userId) ;
}
在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>
在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) ;
}
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. 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 ( ) ) ;
User author = userMapper. selectById ( post. getUserId ( ) ) ;
ret. addObject ( "post" , post) ;
ret. addObject ( "author" , author) ;
ret. addObject ( "page" , commentPage) ;
return ret;
}
}
开发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;
}
}