基于SpringBoot2开发WebApi(五)MySQL分页查询

1.分页查询的意义

随着系统的业务进行,系统产生的数据存储会越来越多,如果根据用户的查询条件一股脑的将所有数据直接返回给前端展示,不仅仅导致查询效率低下,结果集返回的过程也会占用很大的带宽,影响到用户的操作体验。

这个时候我们可以将用户查询条件内的数据采用分页的方式进行,比如,我们将200条数据按每页20条,分10页来返回;由于每次查询我们都是只返回20条,在数据传输过程中大大降低了带宽的要求。

即便查询条件内的结果集中数据有2万条或者更多,每次查询的时候都是只返回当前页的20条数据。对于用户来说,避免了数据量大带来的系统卡顿或者查询等待,大大提升用户体验。

可以把系统分页查询看做类似书籍装订的模式,一本书籍有很多内容,将这些内容分别印刷在不同的纸张上,按顺序进行打上页码,装订起来,用户可以根据页码找到自己想看到的内容。

2.依赖引入

在pom.xml中引入分页查的依赖

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
        </dependency>

3.配置文件

在.yml中增加pagehelper配置

pagehelper:
  helperDialect: mysql
  reasonable: true
  supportMethodsArguments: true
  params: count=countSql

参数说明:

(1)helperDialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:    oracle,mysql,mariadb,sqlite,hsqldb,postgresql,db2,sqlserver,informix,h2,sqlserver2012,derby 

 特别注意:使用 SqlServer2012 数据库时,需要手动指定为sqlserver2012,否则会使用 SqlServer2005 的方式进行分页。你也可以实现AbstractHelperDialect,然后配置该属性为实现类的全限定名称即可使用自定义的实现方法。

(2)offsetAsPageNum:默认值为false,该参数对使用RowBounds作为分页参数时有效。 当该参数设置为true时,会将RowBounds中的offset参数当成pageNum使用,可以用页码和页面大小两个参数进行分页。

(3)rowBoundsWithCount:默认值为false,该参数对使用RowBounds作为分页参数时有效。 当该参数设置为true时,使用RowBounds分页会进行 count 查询。

(4)pageSizeZero:默认值为false,当该参数设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page类型)。

(5)reasonable:分页合理化参数,默认值为false。当该参数设置为true时,pageNum<=0时会查询第一页,pageNum>pages(超过总数时),会查询最后一页。默认false时,直接根据参数进行查询。

(6)params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值, 默认值为:pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。

(7)supportMethodsArguments:支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面params配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的com.github.pagehelper.test.basic包下的ArgumentsMapTest和ArgumentsObjTest。

(8)autoRuntimeDialect:默认值为false。设置为true时,允许在运行时根据多数据源自动识别对应方言的分页 (不支持自动选择sqlserver2012,只能使用sqlserver)。

(9)closeConn:默认值为true。当使用运行时动态数据源或没有设置helperDialect属性自动获取数据库类型时,会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认true关闭,设置为false后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。

4.分页查询使用方法的封装

public class PageUtils {

    public static PageResult getPageResult(PageInfo<?> pageInfo) {
        PageResult pageResult = new PageResult();
        pageResult.setPageNum(pageInfo.getPageNum());
        pageResult.setPageSize(pageInfo.getPageSize());
        pageResult.setTotalSize(pageInfo.getTotal());
        pageResult.setTotalPages(pageInfo.getPages());
        pageResult.setContent(pageInfo.getList());
        return pageResult;
    }
}

PageResult 结果集定义

public class PageResult {
    /**
     * 当前页码
     */
    private int pageNum;
    /**
     * 每页数量
     */
    private int pageSize;
    /**
     * 页码总数
     */
    private int totalPages;

    /**
     * 记录总数
     */
    private long totalSize;

    /**
     * 数据模型
     */
    private List<?> content;
    public int getPageNum() {
        return pageNum;
    }
    public void setPageNum(int pageNum) {
        this.pageNum = pageNum;
    }
    public int getPageSize() {
        return pageSize;
    }
    public void setPageSize(int pageSize) {
        this.pageSize = pageSize;
    }
    public long getTotalSize() {
        return totalSize;
    }
    public void setTotalSize(long totalSize) {
        this.totalSize = totalSize;
    }
    public int getTotalPages() {
        return totalPages;
    }
    public void setTotalPages(int totalPages) {
        this.totalPages = totalPages;
    }
    public List<?> getContent() {
        return content;
    }
    public void setContent(List<?> content) {
        this.content = content;
    }
}

5.在Service里面增加分页实现

在接口对应的Service的方法中,增加对分页查询的实现

    /**
     * 查询用户列表
     * @param key
     * @param pageNum 当前页码
     * @param pageSize 每页显示的条数
     * @return
     */
    public PageResult queryAdminUserList(String key,int pageNum, int pageSize,BigInteger roleId)
    {
        //设置当前查询的页
        PageHelper.startPage(pageNum,pageSize);
        List<AdminUser> adminUserList=adminUserDao.queryAdminUserList(key,roleId);
        //将结果集存储到分页查询统一结果集里面
        PageInfo<AdminUser> pageInfo=new PageInfo<>(adminUserList);
        PageResult pageResult= PageUtils.getPageResult(pageInfo);
        return pageResult;
    }

6.Controller增加分页查询参数的传入

    @CheckToken
    @ApiOperation(value = "用户列表查询", notes = "用户列表查询")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "key",value = "查询条件"),
            @ApiImplicitParam(name = "pageNum",value = "当前页",required = true),
            @ApiImplicitParam(name = "pageSize",value = "每页显示条数",required = true),
            @ApiImplicitParam(name = "roleId",value = "角色id",required = true)
    })
    @ApiResponses({
            @ApiResponse(code = 200,message = "成功",response = AdminUser.class),
    })
    @PostMapping(value = "queryAdminUserList")
    public Result<Object> queryAdminUserList(String key, int pageNum, int pageSize,BigInteger roleId){
        try {
            PageResult pageUserList = adminUserService.queryAdminUserList(key,pageNum,pageSize,roleId);
            return ResultGenerator.success("成功",pageUserList);
        } catch (Exception e) {
            e.printStackTrace();
            return ResultGenerator.error("失败:" + e.getMessage());
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_17486399/article/details/117549216