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("参数验证失败");