首先dao层有dao的实体类,service有它自己的实体类,所以service在调用dao层时有一个补全实体类的逻辑,首先回复可以回复评论,回复也可以回复回复,设计表时需要一个回复人的id和一个被回复人的id,当从数据库中查到数据时返回到service时,先把回复人的id和被回复人的id分别当成两个map中的key存进去,然后在根据各自的id调用用户接口去查询该id下对应的用户昵称,之后把这个昵称分别存到map中,在补全service里面的实体类返回给前台,一共有两个方法 查询和修改,前台展示评论的时候 各自的评论下面只展示两条回复数据,后面会有三个点,当用户点击这三个点的时候,会把该评论下的回复都展示出来,所以前台需要调用后台的回复的查询方法两次,一次是之查找前两条的数据,另一次时所有的全部查询出来,后台只写一个方法就可以加上分页的条件 前台传输数据的时候把分页的字段传给后台,后台去查就可以,添加的时候注意一点 前台传输的时一个dto对象,需要把这个转化成dao层的对象,然后添加就行了
controller层
/**
* 微博回复的查询方法
*
* @param commentsId 评论的id
* @param offset 第几页
* @param size 每一页的条数
* @return Response
*/
@RequestMapping(value = "/getReply", method = RequestMethod.POST)
public Response selectReplyByCommentsId(Long commentsId, Integer offset, Integer size) {
if (null != commentsId && null != offset && null != size) {
try {
PageInfo pageInfo = replyService.selectReplyDto(commentsId, offset, size);
log.info("=查询成功:{}", pageInfo);
return new ObjectResponse(0, "查询成功", pageInfo);
} catch (Exception e) {
log.error("=查询失败:{}", e);
return new Response(2000, "查询失败");
}
} else {
log.info("==查询的参数不能为空:{}:{}:{}", commentsId, offset, size);
return new Response(2000, "查询参数不能为空!");
}
}
/**
* 微博回复的添加方法
*
* @param replyDto 回复的传输层实体类
* @return Response
*/
@RequestMapping(value = "/insertReply", method = RequestMethod.POST)
public Response insetReply(ReplyDto replyDto) {
if (null == userHolder.getCache()) {
return new Response(2018, "用户未登录");
}
//使用后台获取的登录者id覆盖前端传输的id.
replyDto.setCustomerId(userHolder.getCache().getUid());
if (!Strings.isBlank(replyDto.getContentText())) {
if (null != replyDto.getContentText()) {
try {
ReplyDto replyDto1 = replyService.isnsertReplyDto(replyDto);
log.error("添加回复结果为:{}",replyDto1);
if (null != replyDto1) {
return new ObjectResponse(0, "添加成功", replyDto1);
}
return new Response(2000, "添加失败,返回结果为空");
} catch (Exception e) {
log.error("==评论内容不能为空:{}", e);
return new Response(3000, "添加失败");
}
} else {
log.info("==回复内容不能为空:{}", replyDto);
return new Response(3001, "回复内容不能为空");
}
} else {
log.info("==回复内容不能为空:{}", replyDto);
return new Response(3002, "回复内容不能为空");
}
}
service层
package net.nxb.seer.app.services.impl;
import net.nxb.seer.app.services.ReplyService;
import net.nxb.seer.common.customer.domain.Customer;
import net.nxb.seer.common.dao.CustormerDao;
import net.nxb.seer.common.dao.ReplyMapper;
import net.nxb.seer.common.entity.ReplyDo;
import net.nxb.seer.common.page.PageInfo;
import net.nxb.seer.second.dto.ReplyDto;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
/**
* @Auther: wuyongfei
* @Description: 微博回复的业务实现类
* @Date: 2018/8/21 13:43
*/
@Service
public class ReplyServiceImpl implements ReplyService{
@Autowired
private ReplyMapper replyMapper;//回复的dao层对象
@Autowired
private CustormerDao custormerDao; //用户的dao层对象
/**
* 查询回复业务层
* @param commentsId 评论id
* @param offset 第几条数据
* @param size 每页展示页数
* @return 自定义对象 PageInfo
*/
@Override
public PageInfo selectReplyDto(Long commentsId, Integer offset, Integer size) {
//创建返回值对象集合
List<ReplyDto> resultList = new ArrayList<ReplyDto>();
//调用回复dao层查询回复数据
if(null !=commentsId && null != offset && null != size) {
List<ReplyDo> replyDos = replyMapper.selectByCommentsId(commentsId, offset, size + 1);
//创建回复人id集合
List<Long> ids = new ArrayList<>();
//创建被回复人id集合
List<Long> ids1 = new ArrayList<>();
if (null != replyDos && replyDos.size() != 0) {
//遍历对象集合,取出id,放入id集合中
for (ReplyDo replyDo : replyDos) { //将对象中的用户id取出来放入id集合中
ids.add(replyDo.getCustomerId());
ids1.add(replyDo.getReplyTo());
}
if (null != ids && ids.size() != 0 && null != ids1 && ids1.size() != 0){
//调用用户持久层方法,根据id集合查询用户昵称,返回list对象集合
List<Customer> customers = custormerDao.findNameById(ids);
List<Customer> replyTOs = custormerDao.findNameById(ids1);
//根据id集合去查询昵称
Map<Long, String> Names = new HashMap<Long, String>();
Map<Long, String> replyNames = new HashMap<Long, String>();
if (null != customers && customers.size() !=0 ){
//遍历集合,取出对象,
for (Customer customer : customers) {
Names.put(customer.getId(), customer.getNickName()); //将对象id和名称添加到map集合中
}
//遍历被回复人集合,取出对象
for (Customer customer : replyTOs) {
replyNames.put(customer.getId(), customer.getNickName()); //将被回复人对象id和名称添加到map集合中
}
//遍历集合 完善返回对象集合
for (ReplyDo replyDo : replyDos) {
//创建servie传输对象
ReplyDto replyDto = new ReplyDto();
//将dao实体类对象数据copy到传输对象中
BeanUtils.copyProperties(replyDo, replyDto);
//取出用户id,根据用户id在map中查找用户昵称
String name = Names.get(replyDto.getCustomerId());
String name1=replyNames.get(replyDto.getReplyTo());
//将用户name设置到用户传输对象中
replyDto.setCommentsName(name);
replyDto.setReplyToName(name1);
resultList.add(replyDto);
}
}
}
}
}
//判断返回对象集合条数逻辑
if (null ==resultList && resultList.size()==0){
return new PageInfo(false,null);
}
if(resultList.size() <= size){ //如果小于或等于size,表示没有下一页
//创建并返回结果集
return new PageInfo(false,resultList);
}
if (resultList.size() == size+1) { //如果结果集大小等于参数大小+1,代表有下一页
//将集合最后一个删除
resultList.remove(size.intValue());
//创建并返回结果集
return new PageInfo(true,resultList);
}
return new PageInfo(false,null);
}
/**
* 微博添加回复业务层
* @param replyDto 添加对象
*/
@Override
public ReplyDto isnsertReplyDto(ReplyDto replyDto) {
//把值给dao层对象
ReplyDo replyDo=new ReplyDo();
replyDo.setCreateTime(new Date());
BeanUtils.copyProperties(replyDto,replyDo);
//实现添加逻辑
replyMapper.insertReply(replyDo);
Customer customerById = custormerDao.findCustomerById(replyDo.getCustomerId());
Customer customerById1 = custormerDao.findCustomerById(replyDo.getReplyTo());
if (null !=customerById && null !=customerById1){
replyDto.setReplyToName(customerById1.getNickName());
replyDto.setCommentsName(customerById.getNickName());
BeanUtils.copyProperties(replyDo,replyDto);
return replyDto;
}
BeanUtils.copyProperties(replyDo,replyDto);
return replyDto;
}
}
测试出现的Bug1:添加的时候,因为回复既可以回复评论,也可以回复回复,所以当回复评论的时候,此时的被回复的id是空的,这个时候在service中补全的时候一定查不到对应的昵称,而我写的代码中的controller在对前台传入值进行非空判断时是写上的这个被回复人id的这个字段的,所以导致回复回复没问题,但是回复评论的时候始终拦截,因为被回复人的ids始终为空,我第一次改是把它和评论id用|| 然后和其他的字段用&&的,但是后来一想不对劲,因为评论id是必须有的,而被回复人的id是可有可无的 有的话就是回复回复的,没有的话就是回复评论的,这两者没有什么关系。
Bug2:添加的时候,需要再service用的实体类中加入两个字段,一个是回复人的昵称,因为前台展示的效果是这样的注意看,所以添加的时候需要返回一个service对象,然后前端拿到这两个用户的昵称,才能展示给前台,需要改的就是,把返回类型的void改成service对象,然后在service层添加成功后,直接根据service的回复人id和被回复人id调用用户接口查询其用户对象,然后再根据这个对象分别取出这两个对象的名字赋值给service的对象实体类中,然后返回前端(注意:当时改完就直接测试 发现会报个空指针的错误,因为当时我根据用户id调用用户接口查询用户对象时没有这个用户,所以这个查询出来的用户对象是空的,然后调用给用户对象的get方法取用户昵称时肯定会报错,需要加一个非空判断,如果查询的用户为空就不执行赋值过程了,直接把没有用户呢称的service对象返回前台 并提示一个错误 没有该用户即可!)代码如下:回复人的昵称
Bug3:首先就是显示的昵称问题,改了之后始终显示错误,这是因为被回复人可以说空,而回复人不能为空,如果被回复人是空,说明回复的是帖子,如果不为空,说明回复的是回复人,而我当时直接来个非空判断,所以回复人的时候可以 回复帖子的时候就不行了,因为直接拦截了 去掉了非空判断就ok了;