PageHelper的使用
pagehelper是一个分页插件,其工作原理是利用mybatis拦截器,在查询数据库的时候拦截下sql,修改sql使其实现分页效果。
一:配置文件和包
pom.xml引入:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.0</version>
</dependency>
yml:
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
二:使用方法:
方式1:返回pageInfo
@GetMapping("/test1")
@ResponseBody
public PageInfo<Type> getType1(Integer pageNum){
if (pageNum == null) pageNum =1;
PageHelper.startPage(pageNum,5);
List<Type> types = typeService.listType();
PageInfo<Type> pageInfo = new PageInfo<>(types);
return pageInfo;
}
方式2:返回list
@GetMapping("/test2")
@ResponseBody
public List<Type> getType2(Integer pageNum){
if (pageNum == null) pageNum =1;
PageHelper.startPage(pageNum,5);
List<Type> types = typeService.listType();
return types;
}
测试接口分析其不同点:
测试方式1:
{
"total": 8,
"list": [
{
"id": 3,
"name": "分布式"
},
{
"id": 4,
"name": "微服务"
},
{
"id": 5,
"name": "大数据"
},
{
"id": 6,
"name": "spring全家桶"
},
{
"id": 7,
"name": "C语言回顾"
}
],
"pageNum": 1,
"pageSize": 5,
"size": 5,
"startRow": 1,
"endRow": 5,
"pages": 2,
"prePage": 0,
"nextPage": 2,
"isFirstPage": true,
"isLastPage": false,
"hasPreviousPage": false,
"hasNextPage": true,
"navigatePages": 8,
"navigatepageNums": [
1,
2
],
"navigateFirstPage": 1,
"navigateLastPage": 2
}
测试方式2:
[
{
"id": 3,
"name": "分布式"
},
{
"id": 4,
"name": "微服务"
},
{
"id": 5,
"name": "大数据"
},
{
"id": 6,
"name": "spring全家桶"
},
{
"id": 7,
"name": "C语言回顾"
}
]
很明显,pageInfo附带了相关页的信息。
三:考虑方式2中的分页
为什么添加了PageHelper.startPage()方法后就可以达到分页,PageHelper帮我们做了什么?
public String getPageSql(String sql) {
StringBuilder sqlBuilder = new StringBuilder(sql.length() + 120);
sqlBuilder.append("select * from ( select tmp_page.*, rownum row_id from ( ");
sqlBuilder.append(sql);
sqlBuilder.append(" ) tmp_page where rownum <= ? ) where row_id > ?");
return sqlBuilder.toString();
}
pagehelper在执行sql前帮我们修改了sql。
通过控制台我们可以看到sql语句如下:
我们测试(debug)一遍接口:
Test:
在debug过程中可以看到:
pagehelper计算了limit 限制的起始行和结束行
四: PageHelper.startPage()方法的作用域
我们做一个这样的测试:
//test
@GetMapping("/test1")
@ResponseBody
public PageInfo<Type> getType1(Integer pageNum){
if (pageNum == null) pageNum =1;
PageHelper.startPage(pageNum,5);
List<Type> types = getType3();
PageInfo<Type> pageInfo = new PageInfo<>(types);
return pageInfo;
}
public List<Type> getType3(){
List<Type> types = typeService.listType();
return types;
}
问题: 方法1中设置了分页但未执行sql,方法2未设置分页但执行了sql,方法1调用方法2
测试/text1接口发现是可以得到数据的,进入startPage()查看:
显然,startPage()作用于一个线程内,那么思考是否startPage()作用于该线程内的所有sql查询?
测试:
@GetMapping("/test1")
@ResponseBody
public PageInfo<Type> getType1(Integer pageNum){
if (pageNum == null) pageNum =1;
PageHelper.startPage(pageNum,5);
List<Type> types = getType3();
PageInfo<Type> pageInfo = new PageInfo<>(types);
List<Type> types1 = typeService.listType();
PageInfo<Type> pageInfo1 = new PageInfo<>(types1);
return pageInfo1;
}
通过postman测试接口发现并未分页
结论:startPage()作用于一个线程中的下一条查询sql
**注:**一次http请求,Java会开启一个线程处理