Spring Boot整合Mybatis的基础使用-基于PageHelper分页

Spring Boot整合Mybatis的基础使用-基于PageHelper分页

分页乃是我们日常开发中经常遇到的场景,在以前开发基本都是自己手写SQL来进行分页,现在,有很多贴心的大佬为了考虑得非常周到,便给我们提供了PageHelper这个强大的开源分页组件,用起来真是不赖。

PageHelper的基础使用

因为这里是Spring Boot的项目,PageHelper也贴心的提供了PageHelper Starter,这里直接引入即可

1
2
3
4
5
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.3.1</version>
</dependency>

用法很简单,直接调用静态类方法即可

1
PageHelper.startPage(1, 2);

我们来新建一个Controller看看效果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
@RestController
@RequestMapping(value = "demo")
public class DemoController {

@Autowired
UserMapper userMapper;

@GetMapping
public List<User> queryUser(){
//获取第1页,2条内容
PageHelper.startPage(1, 2);
return userMapper.queryUser();
}
}

除了PageHelper.startPage,还可以用PageHelper.offsetPage,只不过offsetPage需要指定从第几条数据开始取,取多少条记录。举个例子

1
2
3
4
//是从第三页开始取,取两条,会取到第5条和第6条数据
PageHelper.startPage(3,2)
//是从第四条开始取,取两条,会取到第4条和第5条
PageHelper.offsetPage(3,2)

PageHelper.startPage除了自己写页码和条数,也可以直接传入HttpServletRequest对象,PageHelper会去URL中找pageNumpageSize

默认情况下,PageHelper会查询会总条数,而且,我们做分页一般也是需要显示总页数的,现在我们就要处理一下,把总页数显示出来,这里我们需要借助pagehelper提供PageInfo类,

1
2
3
4
5
6
7
8
9
10
11
12
13
@RestController
@RequestMapping(value = "demo")
public class DemoController {

@Autowired
UserMapper userMapper;

@GetMapping
public PageInfo<User> queryUser(HttpServletRequest httpServletRequest){
PageHelper.startPage(httpServletRequest);
return new PageInfo<User>(userMapper.queryUser());
}
}

当然,你可能只需要totallist那个就自己再建个Vo类,取PageInfo相应的值即可。

PageHelper 安全调用

  1. 使用 RowBounds 和 PageRowBounds 参数方式是极其安全的

  2. 使用参数方式是极其安全的

  3. 使用 ISelect 接口调用是极其安全的
    ISelect 接口方式除了可以保证安全外,还特别实现了将查询转换为单纯的 count 查询方式,这个方法可以将任意的查询方法,变成一个 select count(*) 的查询方法。

  4. 什么时候会导致不安全的分页?
    PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。

只要你可以保证在 PageHelper 方法调用后紧跟 MyBatis 查询方法,这就是安全的。因为 PageHelper 在 finally 代码段中自动清除了 ThreadLocal 存储的对象。

如果代码在进入 Executor 前发生异常,就会导致线程不可用,这属于人为的 Bug(例如接口方法和 XML 中的不匹配,导致找不到 MappedStatement 时), 这种情况由于线程不可用,也不会导致 ThreadLocal 参数被错误的使用。

但是如果你写出下面这样的代码,就是不安全的用法:

1
2
3
4
5
6
7
PageHelper.startPage(1, 10);
List<Country> list;
if(param1 != null){
list = countryMapper.selectIf(param1);
} else {
list = new ArrayList<Country>();
}

这种情况下由于 param1 存在 null 的情况,就会导致 PageHelper 生产了一个分页参数,但是没有被消费,这个参数就会一直保留在这个线程上。当这个线程再次被使用时,就可能导致不该分页的方法去消费这个分页参数,这就产生了莫名其妙的分页。

上面这个代码,应该写成下面这个样子:

1
2
3
4
5
6
7
List<Country> list;
if(param1 != null){
PageHelper.startPage(1, 10);
list = countryMapper.selectIf(param1);
} else {
list = new ArrayList<Country>();
}

这种写法就能保证安全。

如果你对此不放心,你可以手动清理 ThreadLocal 存储的分页参数,可以像下面这样使用:

1
2
3
4
5
6
7
8
9
10
11
List<Country> list;
if(param1 != null){
PageHelper.startPage(1, 10);
try{
list = countryMapper.selectAll();
} finally {
PageHelper.clearPage();
}
} else {
list = new ArrayList<Country>();
}

这么写很不好看,而且没有必要。

PageHelper 安全调用这一段摘抄自PageHelper官网。更多信息请浏览官方网站获取

Spring Boot整合Mybatis的基础使用-基于PageHelper分页

https://blogs.52fx.biz/posts/3982445681.html

作者

eyiadmin

发布于

2021-08-27

更新于

2024-05-31

许可协议

评论