寻找写代码感觉(十二)之 封装分页请求参数和返回参数

一、写在前面

好在上周的加班,有了些成效,终于不用每天熬着了,可以为那段程序画上一个暂时性的句号了,最后希望项目顺利上线。

二、为什么要进行封装?

  • 学习的角度看,更加贴近了封装的特性,使得代码整洁,复用率高,锻炼自己的能力。
  • 协作的角度看,利人利己。别人调你的方法或者接口,效率更高。

三、如何进行分页请求参数和返回参数的封装

从结果导向来看,就是将入参及返回信息统一化,我们先对请求参数进行改造。

1、入参的改造

新建一个类,并附上页数和每页显示条数两个属性,示例代码如下:

package com.rongrong.wiki.req;

import lombok.Data;

@Data
public class PageReq {
    private int page;
    private int size;
}

这并没有完,因为还要保留原来入参,有时候也许还要用这两个属性,所以这里需要继承PageReq这个类即可,示例代码如下:

package com.rongrong.wiki.req;

public class EBookReq extends PageReq {
    private Long id;

    private String name;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        StringBuilder sb = new StringBuilder();
        sb.append(getClass().getSimpleName());
        sb.append(" [");
        sb.append("Hash = ").append(hashCode());
        sb.append(", id=").append(id);
        sb.append(", name=").append(name);
        sb.append("]");
        return sb.toString();
    }
}

2、返回信息的改造

其实,这么做的好处就是给前端同学更好的表示作用。
未封装前返回信息如下所示:

{
  "success": true,
  "message": "执行查询成功!",
  "content": [
    {
      "id": 1,
      "name": " Spring Boot入门教程 ",
      "category1Id": null,
      "category2Id": null,
      "description": " 零基础入门Java开发,企业级应用开发最佳首选框架",
      "cover": null,
      "docCount": null,
      "viewCount": null,
      "voteCount": null
    },
    {
      "id": 2,
      "name": " Vue 入门教程 ",
      "category1Id": null,
      "category2Id": null,
      "description": " 零基础入门Vue开发,企业级应用开发最佳#电子书表",
      "cover": null,
      "docCount": null,
      "viewCount": null,
      "voteCount": null
    },
    {
      "id": 3,
      "name": " Web 自动化入门教程 ",
      "category1Id": null,
      "category2Id": null,
      "description": " Web自动化测试与Selenium 3.0从入门到实践 #电子书表",
      "cover": null,
      "docCount": null,
      "viewCount": null,
      "voteCount": null
    }
  ]
}

Response code: 200; Time: 226ms; Content length: 585 bytes

接下来我们来进行改造,因为要封装分页,那么肯定需要有共多少也这个属性,其他返回信息统一放到一块去管理,由于不清楚返回类型,我们用泛型T去接收,具体示例代码如下:

package com.rongrong.wiki.req;
@Data
public class PageResp<T> {
    private long totalPages;
    private List<T> list;
}

3、对service及接口进行改造

service层示例代码如下:

package com.rongrong.wiki.service;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rongrong.wiki.domain.EBook;
import com.rongrong.wiki.domain.EBookExample;
import com.rongrong.wiki.mapper.EBookMapper;
import com.rongrong.wiki.req.EBookReq;
import com.rongrong.wiki.req.PageResp;
import com.rongrong.wiki.resp.EBookResp;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import javax.annotation.Resource;
import java.util.List;

import static com.rongrong.wiki.util.CopyUtil.copyList;

/**
 * @author rongrong
 * @version 1.0
 * @description
 * @date 2021/10/13 23:09
 */
@Service
public class EBookService {

    @Resource
    private EBookMapper eBookMapper;

    public PageResp<EBookResp> list(EBookReq eBookReq) {
        EBookExample eBookExample = new EBookExample();
        //此处代码的意思相当于,搞了一个Sql的where条件
        EBookExample.Criteria criteria = eBookExample.createCriteria();
        //划波浪线为不推荐使用,这里我们去看源代码做个替换即可
        if (!ObjectUtils.isEmpty(eBookReq.getName())) {
            criteria.andNameLike("%" + eBookReq.getName() + "%");
        }
        //控制请求后,每页显显示3条数据
        PageHelper.startPage(eBookReq.getPage(), eBookReq.getSize());
        List<EBook> eBookList = eBookMapper.selectByExample(eBookExample);
        PageInfo<EBook> pageInfo = new PageInfo(eBookList);
        System.out.println("共 " + pageInfo.getTotal() + " 条数据");
        System.out.println("共 " + pageInfo.getPages() + " 页");
        //List<EBookResp> eBookRespList = new ArrayList<>();
        //for (EBook eBook: eBookList) {
        //    //EBookResp eBookResp = new EBookResp();
        //    ////spring boot 自带的BeanUtils完成对象的拷贝
        //    //BeanUtils.copyProperties(eBook, eBookResp);
        //    //eBookResp.setId(12345L);
        //    //单体复制
        //    EBookResp copy = copy(eBook, EBookResp.class);
        //    eBookRespList.add(copy);
        //}
        //列表复制
        List<EBookResp> respList = copyList(eBookList, EBookResp.class);
        PageResp pageResp = new PageResp<>();
        pageResp.setTotal(pageInfo.getTotal());
        pageResp.setList(respList);
        return pageResp;
    }
}

接口改造部分示例代码如下:

package com.rongrong.wiki.controller;

import com.rongrong.wiki.req.EBookReq;
import com.rongrong.wiki.req.PageResp;
import com.rongrong.wiki.resp.CommonResp;
import com.rongrong.wiki.resp.EBookResp;
import com.rongrong.wiki.service.EBookService;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;

/**
 * @author longrong.lang
 * @version 1.0
 * @description
 */
@RestController
@RequestMapping("/ebook")
public class EBookController {

    @Resource
    private EBookService eBookService;

    @GetMapping("/list")
    public CommonResp list(EBookReq eBookReq) {
        CommonResp<PageResp<EBookResp>> resp = new CommonResp<>();
        PageResp<EBookResp> list = eBookService.list(eBookReq);
        resp.setMessage("执行查询成功!");
        resp.setContent(list);
        return resp;
    }
}

4、对改造代码进行测试

测试结果如下:

四、写在最后

到此,请求和返回信息的封装介绍完,感兴趣的同学请自行尝试!

posted @ 2021-12-07 21:35  久曲健  阅读(998)  评论(0编辑  收藏  举报