7.4 实战图书详情相关接口(管理员端)

news2024/9/24 1:14:41

CSDN成就一亿技术人

文章目录

  • 前言
  • 一、需求
  • 二、Service层
    • 2.1 图书详情 - 基本信息接口
      • BookDetailBO
      • BookService
      • BookServiceImpl
    • 2.2 图书详情 - 图书评论接口
      • BookCommentBO
      • StudentBO
      • BookCommentService
      • BookCommentServiceImpl
  • 三、Web层
    • BookAdminController
  • 四、PostMan测试
  • 最后


前言

在前面的API开发中,有一些朋友私信我对定义的VO、BO、PO对象存在疑问,不太明白各层定义的对象的好处!都是失血或贫血对象,对象的字段又很相近,传递时拷贝来拷贝去,感觉用起来更麻烦,这么做到底有什么好处呢?

你是否有什么类似的疑问?对于没有实际案例场景的同学,我认为这是很正常的想法。但实际的场景:Service层获取到PO对象后,会根据不同场景做不同的组装、计算等逻辑,所以BO就很必要了!你可以这么想:如果只是对数据库PO的直接映射,是不是Service层都显的鸡肋?所以往往在实际的项目里,Service层才是最厚的那层,才是与你打交道最多的地方,所以对于数据库的PO对象包装一层的BO就很重要,它可以做很多事,慢慢领会吧!这里举一个我见过的最典型的反面例子:用户接口返回了加密后的密码!天呐,这祭天不冤枉吧~~

本文,我会通过需求,完整写出我开发图书详情相关接口(管理员端)的思路,这才是真正的实战!


一、需求

B端管理员端和C端学生端,都有图书详情的模块,大同小异,管理员侧重书评管理,而学生侧重对自己有效的信息。主要区别如下:

  1. B端管理员端:展示图书的所有评论,包括不同状态(0-待审核 1-通过 2-驳回)的评论
  2. C端学生端:展示图书审核通过的评论,以及我是否收藏

本文主要实现的是管理员端


二、Service层

因为图书详情展示的内容较多,所以是需要与前端同学一起来定义,通常有两种做法:

  1. 一个接口,包括详情里的所有信息
  2. 多个接口,每个接口包括部分信息

我这里会采用多个接口的方式,因为对于评论来说,会涉及到分页,一个接口并没有那么好处理!
我拆成两个接口:

  • 图书详情 - 基本信息接口
  • 图书详情 - 图书评论接口

2.1 图书详情 - 基本信息接口

BookDetailBO

图书详情,包括图书的全部信息 + 创建人 + 修改人,我这里直接把PO字段都都拿了过来,实际项目中,尽可能仅返回产品设计原型和PRD中需要的字段。

@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

新增一个获取图书详情的接口方法,像这种见名知义的方法,一般我推荐不写注释。

BookDetailBO getBookDetail(Integer id);

BookServiceImpl

对于实现代码,如果你是一路跟着学过来的同学,我相信你能看懂、会写、可优化下面的代码~

@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;
}

当然,实现有很多方式:分开查询的方式、Join表查询的方式。
这里分开查询,主要考虑的是有缓存优化的空间,如果是Join查询,那么就没什么优化的空间!

2.2 图书详情 - 图书评论接口

BookCommentBO

对于评论列表,因为管理员可以查看全部评论,所以包括图书评论的全部信息 + 学生信息 + 审核人

返回学生信息,也是方便前端进行更丰富的展示,这主要取决于产品设计,大部分通用字段就直接全部返回了。

@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

对于学生StudentBO,管理员可能会查看相关信息,同理~

@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

新增的图书评论接口

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

BookCommentServiceImpl

用到了上一节的分页功能:7.3 SpringBoot整合MyBatis分页插件github.pageHelper:实现图书列表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;
    }

}

三、Web层

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));
}

都是之前讲过的代码,新注入了bookCommentService,并新增了两个接口。


四、PostMan测试

在这里插入图片描述

在这里插入图片描述


最后

想要看更多实战好文章,还是给大家推荐我的实战专栏–>《基于SpringBoot+SpringCloud+Vue前后端分离项目实战》,由我和 前端狗哥 合力打造的一款专栏,可以让你从0到1快速拥有企业级规范的项目实战经验!

具体的优势、规划、技术选型都可以在《开篇》试读!

订阅专栏后可以添加我的微信,我会为每一位用户进行针对性指导!

另外,别忘了关注我:天罡gg ,发布新文不容易错过: https://blog.csdn.net/scm_2008

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/735275.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深入理解Linux内核网络——内核与用户进程协作之同步阻塞方案(BIO)

文章目录 一、相关实际问题二、socket的直接创建三、内核和用户进程协作之阻塞方式1&#xff09;等待接收消息2&#xff09;软中断模块3&#xff09;同步队列阻塞总结 在上一部分中讲述了网络包是如何从网卡送到协议栈的&#xff08;详见深入理解Linux网络——内核是如何接收到…

pycharm连接mysql数据库

点击右侧数据库&#xff0c;点击加号新建&#xff0c;选择数据源&#xff0c;选择mysql 输入数据库相关信息&#xff0c;可以先点击测试连接看能不能连接上&#xff0c; 如果驱动没下载会提示&#xff0c;需要下载驱动&#xff0c;直接点击下载安装即可 测试连接成功 勾选要显示…

LVS +Keepalived高可用群集

文章目录 一、Keepalived概述二、Keepalived服务重要功能1.管理 LVS 负载均衡软件2.支持故障自动切换&#xff08;Failover&#xff09;3.实现 LVS 集群中节点的健康检查&#xff08;Health Checking&#xff09;4.VRRP通信原理 三、keepalived体系主要模块及作用四、keepalive…

docker安装fastdfs(1个tracker、2个storage)

文章目录 1 拉取镜像2 构建tracker容器2.1 创建配置文件和数据文件路径&#xff08;只在主机上创建&#xff09;2.2 在官网下载了原装tracker.conf&#xff0c;修改了一个参数最大并发连接数&#xff0c;max_connections&#xff1a;改为1024&#xff08;默认256&#xff09;2.…

Leetcode-每日一题【2130.链表最大孪生和】

题目 在一个大小为 n 且 n 为 偶数 的链表中&#xff0c;对于 0 < i < (n / 2) - 1 的 i &#xff0c;第 i 个节点&#xff08;下标从 0 开始&#xff09;的孪生节点为第 (n-1-i) 个节点 。 比方说&#xff0c;n 4 那么节点 0 是节点 3 的孪生节点&#xff0c;节点 1 …

线性回归算法

什么是线性回归&#xff1f; 线性回归&#xff08;Linear regression&#xff09;是一种利用线性函数对自变量&#xff08;特征&#xff09;和因变量之间的关系进行建模的方法。线性回归是机器学习中一种广泛使用的基本回归算法。含有有多个特征的线性回归称为多元线性回归。 …

雅思词汇怎样在短期内进行突破?

雅思的考试对词汇量的要求是比较高的&#xff0c;那么该怎样才能高效的积累呢&#xff1f;和小编一起来看看雅思词汇怎样在短期内进行突破&#xff1f; 词汇突破 1&#xff09;制定合理的计划&#xff0c;反复循环 背单词是一个非常繁重的任务&#xff0c;它需要大量的精力。…

【记录】gnuplot|gnuplot怎么把多个图画成一个?

版本&#xff1a;gnuplot 5.2 patchlevel 2 解决了无数次了还是反复忘&#xff0c;气&#xff0c;遂记。 下列程序的功能&#xff1a; 读取文件夹下的所有dat文件&#xff0c;并把所有dat的结果画在一张图里并标好图例&#xff1a; set term png set output "output.png…

ElasticSearch 总结

ElasticSearch 1. 什么是RestFul REST : 表现层状态转化(Representational State Transfer)&#xff0c;如果一个架构符合REST原则&#xff0c;就称它为 RESTful 架构风格。 资源: 所谓"资源"&#xff0c;就是网络上的一个实体&#xff0c;或者说是网络上的一个具…

【简单认识Haproxy搭建Web群集】

文章目录 Haproxy概念1、简介2、HAProxy的主要特性3、HAProxy常见负载均衡策略4、LVS、Nginx、HAproxy的区别&#xff1a; 部署实例1.节点服务器部署2.部署Haproxy服务器3、日志定义 Haproxy概念 1、简介 HAProxy是可提供高可用性、负载均衡以及基于TCP和HTTP应用的代理&…

mmlab框架的train.txt/val.txt等制作

文件组织形式&#xff1a; 代码和数据集位于同一级目录 以下需要修改的地方已经标注&#xff1a; import os import random #------------基本参数&#xff08;修改下面4个&#xff09;----------------# trainval_percent 0.8#用于训练&评估的比例 train_percent 0.7…

SpringBoot 如何使用 MockMvc 进行 Web 集成测试

SpringBoot 如何使用 MockMvc 进行 Web 集成测试 介绍 SpringBoot 是一个流行的 Java Web 开发框架&#xff0c;它提供了一些强大的工具和库&#xff0c;使得开发 Web 应用程序变得更加容易。其中之一是 MockMvc&#xff0c;它提供了一种测试 SpringBoot Web 应用程序的方式&…

实测:python字典迭代比列表迭代快

具体原因可以参考&#xff1a;Python中字典比列表快的原因是什么 - 风纳云 (fengnayun.com) 再补充一点&#xff0c;字典的键可以直接迭代&#xff0c;但是value不行。 此时红色框部分似乎dict&#xff0c;速度很快&#xff1b; 但是当换成列表的时候 &#xff1a; 有一点外…

线性表的链式表示和实现

链式表示中各节点由两个域组成&#xff1a; 数据域&#xff1a;存储元素值数据 指针域&#xff1a;存储直接后继节点的存储位置 头指针、头节点、首元节点&#xff1a;示意图 头指针&#xff1a;是指向链表中第一个节点的指针 首元节点&#xff1a;是链表中存储第一个数据元素…

【Unity3D】动态路径特效

1 前言 本文通过导航系统&#xff08;NavMeshAgent&#xff09;和线段渲染器&#xff08;LineRenderer&#xff09;实现了角色走迷宫和绘制路径功能&#xff0c;同时实现动态路径特效。 导航系统的介绍详见博客&#xff1a;导航系统、分离路面导航、动态路障导航。线段渲染器的…

RV1126笔记三十七:PaddleOCR检测模型训练

若该文为原创文章&#xff0c;转载请注明原文出处。 PaddleOCR检测模型训练及验证测试 1、准备数据集 在PaddleOCR目录下新建文件夹&#xff1a;train_data, 这个文件夹用于存放数据集的。 使用的是网上大佬提供的车牌识别数据集&#xff0c;下载后&#xff0c;解压到train…

《机器学习公式推导与代码实现》chapter21-贝叶斯概率模型

《机器学习公式推导与代码实现》学习笔记&#xff0c;记录一下自己的学习过程&#xff0c;详细的内容请大家购买作者的书籍查阅。 贝叶斯概率模型 1 贝叶斯定理简介 贝叶斯定理认为任意未知量 θ \theta θ都可以看做一个随机变量&#xff0c;对该未知量的描述可以用一个概率…

如何编写联邦学习训练框架——Pytorch实现

联邦学习框架实现 联邦学习训练过程由服务器和客户端两部分组成。 客户端将本地数据训练得到的模型上传服务器&#xff0c;服务器通过聚合客户端上传的服务器再次下发新一轮的模型&#xff0c;原理很简单&#xff0c;那么我们开始动手写代码。 1. 客户端部分&#xff1a; 客…

LVS - DR群集

文章目录 一、DR模式 LVS负载均衡群集1.数据包流向分析 二、LVS-DR模式的特点三、LVS-DR中的ARP问题四、DR模式 LVS负载均衡群集部署1.环境准备2.配置负载调度器&#xff08;192.168.40.104&#xff09;2.1.配置虚拟 IP 地址&#xff08;VIP&#xff1a;192.168.40.180&#xf…

RabbitMQ在SpringBoot中的高级应用(1)

启动RabbitMQ 1. 在虚拟机中启动RabbitMQ,要先切换到root用户下: su root 2.关闭防火墙: systemctl stop firewalld 3.rabbitmq-server start # 启用服务 4.rabbitmq-server -detached # 后台启动 1.消息确认机制 有两种确认的方式: 自动ACK:RabbitMQ将消息发送给…