业务流程:
1、先创建帖子的实体DiscussPost,属性有帖子id,user_id,title,content,type,status,create_time,comment_count,score,常规的生成set,get方法以及toString()方法。
2、在dao层创建帖子的接口,加上Mapper注解给容器管理类,声明一些对数据库进行操作的方法,以及在resource文件夹下的mapper文件中建立相应的mybatis的xml映射文件,文件的格式可在mybatis官网复制。
List selectDiscussPosts(int userId, int offset, int limit);
// @Param注解用于给参数取别名,
// 如果只有一个参数,并且在里使用,则必须加别名.
int selectDiscussPostRows(@Param("userId") int userId);
int insertDiscussPost(DiscussPost discussPost);
DiscussPost selectDiscussPostById(int userId);
int updateCommentCount(int id, int commentCount);
3、在Service层写处理业务相关代码,如新增一个帖子,先判断帖子是否不为空,然后进行转义HTML标记以及过滤敏感词,最后调用mapper层的插入帖子方法。
public int addDiscussPost(DiscussPost post) { if(post == null) { throw new IllegalArgumentException("参数不能为空!"); } //转义HTML标记 post.setTitle(HtmlUtils.htmlEscape(post.getTitle())); post.setContent(HtmlUtils.htmlEscape(post.getContent())); //过滤敏感词 post.setTitle(sensitiveFilter.filter(post.getTitle())); post.setContent(sensitiveFilter.filter(post.getContent())); return discussPostMapper.insertDiscussPost(post); }
4、在Controller层处理浏览器的请求,在类前加上注解@Controller,@RequestMapping("/discuss")说明这个类下的访问路径都是在/discuss路径下的。
判断当前登录用户不为空,然后新建一个帖子对象,将浏览器传来的数据赋值给post对象,再调用Service层的新增帖子方法,将浏览器新建的帖子新增进数据库,最后返回json格式的数据,0代表成功状态,发布成功。
@RequestMapping(path = "/add", method = RequestMethod.POST) @ResponseBody//给浏览器返回json格式数据 public String addDiscussPost(String title, String content) { User user = hostHolder.getUser(); if (user == null) { return CommunityUtil.getJSONString(403, "你还没有登录"); } DiscussPost post = new DiscussPost(); post.setUserId(user.getId()); post.setTitle(title); post.setContent(content); post.setCreateTime(new Date()); discussPostService.addDiscussPost(post); return CommunityUtil.getJSONString(0,"发布成功"); }
5、前端使用AJAX异步发送请求
$(function(){
$("#publishBtn").click(publish);
});
function publish() {
$("#publishModal").modal("hide");//隐藏发布帖子的输入框
// 获取标题和内容
var title = $("#recipient-name").val();
var content = $("#message-text").val();
// 发送异步请求(POST)
$.post(
CONTEXT_PATH + "/discuss/add",
{"title":title,"content":content},
function(data) {
data = $.parseJSON(data);
// 在提示框中显示返回消息
$("#hintBody").text(data.msg);
// 显示提示框
$("#hintModal").modal("show");
// 2秒后,自动隐藏提示框
setTimeout(function(){
$("#hintModal").modal("hide");
// 刷新页面
if(data.code == 0) {
window.location.reload();
}
}, 2000);
}
);
}
1、在DiscussPostMapper中新增根据id查找帖子的方法,并在相应的mybatis文件中新增对数据库的方法。
2、在DiscussPostService中新增根据id查找帖子的方法,业务比较简单,只是调用mapper中对应查找的方法,注意返回类型是DiscussPost类型。
3、在DiscussPostController中获取浏览器地址栏中帖子的id,然后根据id查找数据库中对应的帖子,以及当前登录的用户信息,通过Model返回给前端页面。
@RequestMapping(path = "/detail/{discussPostId}", method = RequestMethod.GET) public String getDiscussPost(@PathVariable("discussPostId") int discussPostId, Model model) { //帖子 DiscussPost post = discussPostService.findDiscussPostById(discussPostId); model.addAttribute("post", post); //作者 User user = userService.findUserById(post.getUserId()); model.addAttribute("user",user); return "/site/discuss-detail"; }
数据库comment表的设计 :id(评论id),user_id,entity_type(1代表是对帖子的评论,2代表是回复别人的评论),entity_id,target_id,content,status,create_time
业务流程如上图所示,数据层,业务层,表现层。
@Mapper
public interface CommentMapper {
List selectCommentsByEntity(int entityType, int entityId, int offset, int limit);
int selectCountByEntity(int entityType, int entityId);
int insertComment(Comment comment);
}
@Service
public class CommentService implements CommunityConstant {
@Autowired
private CommentMapper commentMapper;
@Autowired
private SensitiveFilter sensitiveFilter;
@Autowired
private DiscussPostService discussPostService;
public List findCommentsByEntity(int entityType, int entityId, int offset, int limit) {
return commentMapper.selectCommentsByEntity(entityType, entityId, offset, limit);
}
public int findCommentCount(int entityType, int entityId) {
return commentMapper.selectCountByEntity(entityType, entityId);
}
public Comment findCommentsById(int id) {
return commentMapper.findCommentsById(id);
}
//添加评论和更新帖子评论数量需要同时进行,放在一个事务之中
@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
public int addComment(Comment comment) {
if (comment == null) {
throw new IllegalArgumentException("参数不能为空!");
}
// 添加评论
comment.setContent(HtmlUtils.htmlEscape(comment.getContent()));
comment.setContent(sensitiveFilter.filter(comment.getContent()));
int row = commentMapper.insertComment(comment);
// 更新帖子评论数量
if (comment.getEntityType() == ENTITY_TYPE_POST) {
int count = commentMapper.selectCountByEntity(comment.getEntityType(), comment.getEntityId());
discussPostService.updateCommentCount(comment.getEntityId(), count);
}
return row;
}
}
/**
* 每一个会话加入私信数量,未读数量,自己发送私信的target
* 总的未读消息数量
*/
@RequestMapping(path = "/letter/list", method = RequestMethod.GET)
public String getLetterList(Model model, Page page) {
User user = hostHolder.getUser();
//分页信息
page.setLimit(5);
page.setPath("/letter/list");
page.setRows(messageService.findConversationCount(user.getId()));
List conversationList = messageService.findConversations(user.getId(), page.getOffset(), page.getLimit());
List
@RequestMapping(path = "/letter/send", method = RequestMethod.POST)
@ResponseBody
public String sendLetter(String toName, String content) {
User target = userService.findUserByName(toName);
if (target == null) {
return CommunityUtil.getJSONString(1, "目标用户不存在!");
}
Message message = new Message();
message.setFromId(hostHolder.getUser().getId());
message.setToId(target.getId());
if (message.getFromId() < message.getToId()) {
message.setConversationId(message.getFromId() + "_" + message.getToId());
}else {
message.setConversationId(message.getToId() + "_" + message.getFromId());
}
message.setContent(content);
message.setCreateTime(new Date());
messageService.addMessage(message);
return CommunityUtil.getJSONString(0);
}