电子书查询列表接口开发

sql 复制代码
# 电子书表

drop table if exists `ebook`;
create table `ebook` (
    `id` bigint not null comment 'id',
    `name` varchar(50) comment '名称',
    `category1_id` bigint comment '分类1',
    `category2_id` bigint comment '分类2',
    `description` varchar(200) comment '描述',
    `cover` varchar(200) comment '封面',
    `doc_count` int comment '文档数',
    `view_count` int comment '阅读数',
    `vote_count` int comment '点赞数',
    primary key (`id`)
) engine=innodb default charset=utf8mb4 comment='电子书';

insert into `ebook` (id, name, description) values (1, 'Spring Boot 入门教程', '零基础入门 Java 开发,企业级应用开发最佳首选框架');
insert into `ebook` (id, name, description) values (2, 'Vue 3 实战指南', '全面讲解 Vue 3 新特性及企业级项目实践');
insert into `ebook` (id, name, description) values (3, 'MySQL 数据库优化', '深入理解数据库原理,掌握性能优化技巧');
insert into `ebook` (id, name, description) values (4, '微服务架构设计', '从单体应用到微服务的完整转型指南');
insert into `ebook` (id, name, description) values (5, 'Docker 容器化部署', '容器化技术原理与实践,助力 DevOps 流程');
insert into `ebook` (id, name, description) values (6, 'Redis 深度历险', '高性能缓存与分布式存储的核心技术解析');

包装

Spring会自动将请求参数映射到类属性,只要名称匹配

GET /ebook/list?name=Spring&category1Id=1&viewCount=100

Controller方法:

java

@GetMapping("/ebook/list")

public List list(EbookReq req) {

// Spring自动创建EbookReq对象并设置属性

return ebookService.list(req);

}

封装请求参数和返回参数

1. 封装请求参数(如 EbookReq)

不封装的坏处:

java 复制代码
// 混乱的参数列表
@GetMapping("/list")
public CommonResp list(String name, Long category1Id, Long category2Id, 
                      Integer minViewCount, Integer maxViewCount, 
                      Integer page, Integer size, String sortBy, String order) {
    // 参数太多,难以维护!
}

封装的好处:

① 代码整洁性

java 复制代码
// 清晰的接口
@GetMapping("/list")
public CommonResp<List<EbookResp>> list(EbookReq req) {
    // 只需要一个参数对象
}

② 易于扩展

java 复制代码
public class EbookReq {
    private String name;
    private Long category1Id;
    private Long category2Id;
    private String description;
    private Integer minViewCount;
    private Integer maxViewCount;
    private Integer page = 1;    // 默认值
    private Integer size = 10;   // 默认值
    
    // 新增字段时,只需要在这里添加,不影响接口签名
    private String author;       // 新增作者字段
}

2. 封装返回参数(如 CommonResp)

直接返回数据的坏处:

java 复制代码
// 前端难以处理各种情况
@GetMapping("/list")
public List<EbookResp> list(EbookReq req) {
    return ebookService.list(req);
    // 问题:如何表示失败?如何返回错误信息?如何统一格式?
}

封装返回的好处:

① 统一响应格式

java 复制代码
public class CommonResp<T> {
    private boolean success;     // 是否成功
    private String message;      // 提示信息
    private String code;         // 状态码
    private T data;              // 业务数据
    
    // 成功响应
    public static <T> CommonResp<T> success(T data) {
        CommonResp<T> resp = new CommonResp<>();
        resp.setSuccess(true);
        resp.setMessage("成功");
        resp.setCode("200");
        resp.setData(data);
        return resp;
    }
    
    // 失败响应
    public static <T> CommonResp<T> error(String message) {
        CommonResp<T> resp = new CommonResp<>();
        resp.setSuccess(false);
        resp.setMessage(message);
        resp.setCode("500");
        return resp;
    }
}

② 便于前端处理

javascript 复制代码
// 前端调用后统一处理
axios.get('/ebook/list').then(response => {
    const resp = response.data;
    if (resp.success) {
        // 处理业务数据
        const ebooks = resp.data;
        displayEbooks(ebooks);
    } else {
        // 统一错误处理
        showError(resp.message);
    }
});

③ 支持复杂场景

java 复制代码
// 成功响应
CommonResp<List<EbookResp>> successResp = CommonResp.success(ebookList);

// 失败响应(业务逻辑错误)
CommonResp<List<EbookResp>> errorResp = CommonResp.error("查询失败");

// 异常响应(全局异常处理器自动封装)
throw new BusinessException("参数验证失败");
相关推荐
实名上网宋凯宣8 小时前
Django
后端·python·django
利威尔xu9 小时前
Go IM 源码实战(14):本地缓存快 3000 倍,失效却难 10 倍
后端·缓存·微服务·面试·golang
逃逸线LOF10 小时前
Ribbon负载均衡原理(Irule组件、源码分析)
后端·spring cloud·ribbon
慢云智慧空间10 小时前
从设备智能到空间理解,空间智能终端解决方案商如何重新定义行业标准
后端
利威尔xu10 小时前
Go IM 源码实战(13):30 个会话只有 2 个红点,未读数错在三条路径
redis·后端·微服务·面试·golang
薛定谔的猫-菜鸟程序员11 小时前
软件架构设计师开发资料大全(从入门到精通)
后端·python·系统架构·flask·架构设计师
IT_陈寒13 小时前
SpringBoot多环境配置把我坑惨了,这个踩坑经验你最好看看
前端·人工智能·后端
码事漫谈13 小时前
DeepSeek 搞了个 "Super-agent",但不是超级智能
后端
吴凡wudianmei13 小时前
从 0 搭一个 AI Agent(四):SSE 跑通之后,三处“契约错配”与它们的修复边界
前端·后端·aigc
小兔子13 小时前
defer 的参数在写下那一刻就求值了,循环里这样写会踩坑
后端