使用mybatis时,最容易遇到的需求就是分页查询了。借助pagehelper分页插件可以快速的实现分页功能。而且这个插件的优点是分页与mapper.xml完全解耦,有效的避免了直接写分页sql来实现分页功能。
一、分页插件原理
分页插件的基本原理是使用mybatis提供的 插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的sql,然后重写sql,添加对应的分页语句及分页参数。
举例:SELECT * FROM diagnosis,拦截sql后重写为:select t.* from (SELECT * FROM diagnosis) t LIMIT 0,10
<!-- 分页依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
二、mapper.xml文件配置:
<select id="findByCountryProjectName" resultType="cn.hsa.pss.pw.web.jsyb.local.entity.DiagnosisDO">
select * from diagnosis
<where>
<if test="countryProjectName != null and countryProjectName != ''">
country_project_name like "%"#{countryProjectName}"%"
</if>
</where>
</select>
说明如下:
1、使用pagehelper进行分页查询时,,无需写分页语句,对于其他的查询条件可正常编写。
2、模糊查询指令:like "%"#{查询条件}"%"
三、 在代码中使用
//dao代码片段
List<DiagnosisDO> findByCountryProjectName(@Param("countryProjectName") String countryProjectName);
说明如下:
1、dao层代码入参中只需写查询条件,无需写分页入参 。
public PageInfo<DiagnosisDO> findByCountryProjectName(String countryProjectName, int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<DiagnosisDO> list = diagnosisDAO.findByCountryProjectName(countryProjectName);
Long total = 0L;
if (!list.isEmpty()) {
//查询总数
total = diagnosisDAO.findDiagnosisCount(countryProjectName);
}
PageInfo<DiagnosisDO> pageInfo = new PageInfo<>();
pageInfo.setList(list);
pageInfo.setPageNum(pageNum);
pageInfo.setPageSize(pageSize);
pageInfo.setTotal(total);
return pageInfo;
}
使用PageInfo对象包装查询结果,无需在查询总数,代码优化如下:
public PageInfo<DiagnosisDO> findByCountryProjectName(String countryProjectName, int pageNum, int pageSize) {
PageHelper.startPage(pageNum, pageSize);
List<DiagnosisDO> list = diagnosisDAO.findByCountryProjectName(countryProjectName);
PageInfo<DiagnosisDO> pageInfo = new PageInfo(list);
return pageInfo;
}
说明如下:
1、PageHelper.startPage(pageNum, pageSize); 引入分页查询,pageNum:页码,pageSize:每页显示数量。
2、一定要在查询之前引入,它会自动对该代码下的第一个查询进行分页,即: findByCountryProjectName。
3、查询结果使用PageInfo包装,无需再查询总数,减少与数据库交互,返回的对象信息如下,total为总数:
{ "total": 0, "list": [], "pageNum": 1, "pageSize": 7, "size": 0, "startRow": 0, "endRow": 0, "pages": 0, "prePage": 0, "nextPage": 0, "isFirstPage": true, "isLastPage": true, "hasPreviousPage": false, "hasNextPage": false, "navigatePages": 8, "navigatepageNums": [], "navigateFirstPage": 0, "navigateLastPage": 0 }
四、接收分页结果数据
场景:核心业务接口数据返回的是分页格式,接收返回结果后在提供给第三方使用。涉及分页结果的接收。
假设核心业务接口返回分页出参结果如下:
String res = "{\n" +
" \"code\": 0,\n" +
" \"data\": {\n" +
" \"recordCounts\": 18795,\n" +
" \"pages\": 1880,\n" +
" \"size\": 10,\n" +
" \"startRow\": 1,\n" +
" \"data\": [\n" +
" {\n" +
" \"lastPage\": false,\n" +
" \"nextPage\": 0,\n" +
" \"poolareaNo\": \"519900\",\n" +
" \"pageSize\": 0,\n" +
" \"crteOptinsNo\": \"100102\",\n" +
" \"opterName\": \"liuxl\",\n" +
" \"rid\": \"424\",\n" +
" \"crteTime\": 1574835451000,\n" +
" \"valiFlag\": \"1\",\n" +
" \"pages\": 0,\n" +
" \"bankNo\": \"103651090037\",\n" +
" \"optTime\": 1593507492000,\n" +
" \"bankcode\": \"103651090037\",\n" +
" \"opterId\": \"111\",\n" +
" \"startRow\": 0,\n" +
" \"prePage\": 0,\n" +
" \"endRow\": 0,\n" +
" \"crterName\": \"liuxl\",\n" +
" \"bankAbbr\": \"农业银行成都锦江支行\",\n" +
" \"addrCityCoty\": \"四川省省本级\",\n" +
" \"pageNum\": 0,\n" +
" \"crterId\": \"111\",\n" +
" \"recordCounts\": 0,\n" +
" \"bankId\": \"00000000000004\",\n" +
" \"size\": 0,\n" +
" \"firstPage\": false,\n" +
" \"optinsNo\": \"519900\",\n" +
" \"bankTypeCode\": \"103\"\n" +
" }\n" +
" ],\n" +
" \"firstPage\": true,\n" +
" \"lastPage\": false,\n" +
" \"pageSize\": 10,\n" +
" \"endRow\": 10,\n" +
" \"pageNum\": 1\n" +
" },\n" +
" \"type\": \"success\",\n" +
" \"message\": \"查询成功\"\n" +
"}";
JSONObject jsb = JSONObject.parseObject(res);
方法一、使用pageResult。
List<BankBasInfoDTO> bankBasInfoDTOS = jsb.getJSONObject("data").getJSONArray("data").toJavaList(BankBasInfoDTO.class);
PageResult pageResult = jsb.getJSONObject("data").toJavaObject(PageResult.class);
pageResult.setData(bankBasInfoDTOS);
return pageResult;
方法二、使用 pageInfo。
pageInfo.setList(bankBasInfoDTOS);
pageInfo.setTotal(jsb.getJSONObject("data").getInteger("recordCounts"));
pageInfo.setPageNum(Integer.parseInt(searchBankDTO.getPageNum()));
pageInfo.setPageSize(Integer.parseInt(searchBankDTO.getPageSize()));