7.4 Interfaces related to actual combat book details (administrator side)

CSDN achieves 100 million technicians


foreword

In the previous API development, some friends privately messaged me that I have doubts about the defined VO, BO, and PO objects, and they don’t quite understand the benefits of the objects defined at each layer! They are all blood loss or anemia objects, and the fields of the objects are very similar. When passing them, they are copied and copied. It feels more troublesome to use. What are the benefits of doing so?

Do you have any similar questions? For students who do not have actual case scenarios, I think this is a normal idea. But the actual scenario: After the Service layer obtains the PO object, it will do different assembly, calculation and other logic according to different scenarios, so BO is very necessary! You can think of it this way: if it's just a direct mapping to the database PO, isn't it that the Service layer is weak? So often in actual projects, the Service layer is the thickest layer and the place where you deal with the most, so it is very important to wrap a layer of BO for the PO object of the database. It can do many things, and slowly Get it! Here's one of the most typical negative examples I've seen: the user interface returns encrypted passwords! Oh my god, this sacrifice to heaven is not unfair~~

In this article, I will fully write out my idea of ​​developing the book details related interface (administrator side) through the requirements. This is the real actual combat!


1. Demand

Both the B-side administrator side and the C-side student side have modules for book details, which are similar with minor differences. Administrators focus on information that is useful to them 书评管理, while students focus on information that is useful to them. The main differences are as follows:

  1. B-side administrator side: display books 所有评论, including comments with different statuses (0-to be reviewed, 1-passed, 2-rejected)
  2. C-end student end: display books 审核通过的评论, and我是否收藏

This article mainly implements the administrator side


2. Service layer

Because there are many contents displayed in the book details, it needs to be defined together with the front-end classmates. There are usually two methods:

  1. An interface, including all the information in the details
  2. Multiple interfaces, each including partial information

The way I will here 采用多个接口, because for comments, pagination will be involved, and an interface is not so easy to handle!
I split it into two interfaces:

  • Book Details - Basic Information Interface
  • Book Details - Book Review Interface

2.1 Book Details - Basic Information Interface

BookDetailBO

Book details, including 图书的全部信息 + 创建人 + 修改人, I directly took all the PO fields here. In the actual project, only the fields required in the product design prototype and PRD should be returned as much as possible.

@Data
public class BookDetailBO implements Serializable {
    
    
    private Integer id;
    private String bookNo;
    private String bookName;
    private Integer bookType;
    private String author;
    private String description;
    private String publisher;
    private Date publishDate;
    private String coverImage;
    private Integer status;
    private Integer borrowCount;
    private Integer commentCount;
    private Boolean isRecommend;
    private Integer createUserId;
    private Integer modifyUserId;
    private Date gmtCreate;
    private Date gmtModified;
    // Book外的字段
    private String createUserName;
    private String modifyUserName;
}

BookService

Add an interface method for obtaining book details. Generally, I recommend not to write comments for such a well-known method.

BookDetailBO getBookDetail(Integer id);

BookServiceImpl

For the implementation code, if you are a classmate who has followed along the way, I believe you can understand, write, and optimize the following code~

@Override
public BookDetailBO getBookDetail(Integer id) {
    
    
    // 图书基本信息
    Book book = bookMapper.selectByPrimaryKey(id);
    if (book == null) {
    
    
        return null;
    }
    BookDetailBO detailBO = new BookDetailBO();
    BeanUtils.copyProperties(book, detailBO);
    // 图书创建人
    User createUser = userMapper.selectByPrimaryKey(book.getCreateUserId());
    detailBO.setCreateUserName(createUser.getUserName());
    if (book.getModifyUserId() != null) {
    
    
        // 图书修改人
        if (book.getCreateUserId().equals(book.getModifyUserId())) {
    
    
            detailBO.setModifyUserName(createUser.getUserName());
        } else {
    
    
            User modifyUser = userMapper.selectByPrimaryKey(book.getModifyUserId());
            detailBO.setModifyUserName(modifyUser.getUserName());
        }
    }
    return detailBO;
}

Of course, there are many ways to implement: the way of separate query, the way of join table query.
Separate query here, the main consideration is 缓存优化the available space, if it is a Join query, then there is no room for optimization!

2.2 Book Details - Book Review Interface

BookCommentBO

For the list of comments, include since the administrator can view all comments 图书评论的全部信息 + 学生信息 + 审核人.

Returning student information is also convenient for the front end to display more abundantly, which mainly depends on product design, and most common fields are returned directly.

@Data
public class BookCommentBO implements Serializable {
    
    
    private Integer id;
    private Integer studentId;
    private Integer bookId;
    private Integer score;
    private String comment;
    private Integer status;
    private Date verifyTime;
    private Integer verifyUserId;
    private Date gmtCreate;
    private Date gmtModified;
    // BookComment以外的字段
    private StudentBO student;
    private String verifyUserName;
}

StudentBO

For the student StudentBO, the administrator may check the relevant information, the same reason~

@Data
public class StudentBO implements Serializable {
    
    
    private Integer id;
    private Integer userId;
    private String studentNo;
    private String studentName;
    private String nickName;
    private String department;
    private String idCardImage;
    private Boolean isApproved;
    private Boolean isFrozen;
    private Date gmtCreate;
    private Date gmtModified;
}

BookCommentService

Added book review interface

public interface BookCommentService {
    
    
    Page<BookCommentBO> getBookCommentPage(int pageNum, int pageSize, int bookId);
}

BookCommentServiceImpl

The paging function in the previous section is used: 7.3 SpringBoot integrates the MyBatis paging plugin github.pageHelper: implements the book list API

@Service
public class BookCommentServiceImpl implements BookCommentService {
    
    

    @Autowired
    private BookCommentMapper bookCommentMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private UserMapper userMapper;

    @Override
    public Page<BookCommentBO> getBookCommentPage(int pageNum, int pageSize, int bookId) {
    
    
        // 图书的评论列表
        BookCommentExample example = new BookCommentExample();
        example.createCriteria().andBookIdEqualTo(bookId);
        // 查询并分页
        Page<BookComment> page = PageHelper.startPage(pageNum, pageSize)
                .doSelectPage(() -> bookCommentMapper.selectByExample(example));
        Page<BookCommentBO> pageBO = new Page<>();
        BeanUtils.copyProperties(page, pageBO);
        for (BookComment bookComment : page.getResult()) {
    
    
            BookCommentBO bookCommentBO = new BookCommentBO();
            BeanUtils.copyProperties(bookComment, bookCommentBO);
            Student student = studentMapper.selectByPrimaryKey(bookCommentBO.getStudentId());
            // 评论的学生
            StudentBO studentBO = new StudentBO();
            BeanUtils.copyProperties(student, studentBO);
            bookCommentBO.setStudent(studentBO);
            // 审核人
            if (bookCommentBO.getVerifyUserId() != null) {
    
    
                User verifyUser = userMapper.selectByPrimaryKey(bookCommentBO.getVerifyUserId());
                bookCommentBO.setVerifyUserName(verifyUser.getUserName());
            }
            pageBO.add(bookCommentBO);
        }
        return pageBO;
    }

}

3. Web layer

BookAdminController

@Autowired
private BookService bookService;
@Autowired
private BookCommentService bookCommentService;

@GetMapping("/book/detail")
public TgResult<BookDetailBO> getBookDetail(@RequestParam("id") Integer id) {
    
    
    return TgResult.ok(bookService.getBookDetail(id));
}

@GetMapping("/book/comment/list")
public TgResult<BookCommentBO> getBookCommentList(@RequestParam("pageNum") Integer pageNum
        , @RequestParam("pageSize") Integer pageSize, @RequestParam("id") Integer id) {
    
    
    return TgResult.ok(bookCommentService.getBookCommentPage(pageNum, pageSize, id));
}

All the codes mentioned before, newly injected bookCommentService, and added two new interfaces.


Four, PostMan test

insert image description here

insert image description here


at last

If you want to read more practical articles, I still recommend my practical column –> "Based on SpringBoot+SpringCloud+Vue Front-end Separation Project Combat", a column jointly created by me and the front-end dog brother, which allows you to learn from From 0 to 1, you can quickly have practical experience in enterprise-level standardized projects!

Specific advantages, planning, and technology selection can all be read in " The Beginning "!

After subscribing to the column, you can add my WeChat, and I will provide targeted guidance for each user!

In addition, don't forget to follow me: Tiangang gg , it is not easy to miss new articles: https://blog.csdn.net/scm_2008

Guess you like

Origin blog.csdn.net/scm_2008/article/details/131620694