PageHelper使用学习

1、添加依赖:

1 <dependency>
2   <groupId>com.github.pagehelper</groupId>
3   <artifactId>pagehelper</artifactId>
4   <version>4.2.1</version>
5 </dependency>

2、在配置文件中添加配置:

 1 <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
 2     <property name="dataSource" ref="dataSource"/>
 3     <property name="mapperLocations" value="classpath:mapper/*.xml"/>
 4     <property name="typeAliasesPackage" value="com.demo.entity"/>
 5 
 6     <property name="plugins">
 7         <array>
 8             <bean class="com.github.pagehelper.PageHelper">
 9                 <property name="properties">
10                     <value>
11                         helperDialect=mysql
12                         reasonable=true
13                         supportMethodsArguments=true
14                         params=count=countSql
15                     </value>
16                 </property>
17             </bean>
18         </array>
19     </property>
20 </bean>

3、PageHelper代码添加:

1 public PageInfo<ProType> selectlist() {
2     PageHelper.startPage(1, 5);
3     List<ProType> list = proTypeMapper.selectlist();
4 
5     PageInfo page = new PageInfo(list);
6     return page;
7 }

4、支持的几种调用方式:

 1 //第一种,RowBounds方式的调用
 2 List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));
 3 
 4 //第二种,Mapper接口方式的调用,推荐这种使用方式。
 5 PageHelper.startPage(1, 10);
 6 List<Country> list = countryMapper.selectIf(1);
 7 
 8 //第三种,Mapper接口方式的调用,推荐这种使用方式。
 9 PageHelper.offsetPage(1, 10);
10 List<Country> list = countryMapper.selectIf(1);
11 
12 //第四种,参数方法调用
13 //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
14 public interface CountryMapper {
15     List<Country> selectByPageNumSize(
16             @Param("user") User user,
17             @Param("pageNum") int pageNum,
18             @Param("pageSize") int pageSize);
19 }
20 //配置supportMethodsArguments=true
21 //在代码中直接调用:
22 List<Country> list = countryMapper.selectByPageNumSize(user, 1, 10);
23 
24 //第五种,参数对象
25 //如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
26 //有如下 User 对象
27 public class User {
28     //其他fields
29     //下面两个参数名和 params 配置的名字一致
30     private Integer pageNum;
31     private Integer pageSize;
32 }
33 //存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
34 public interface CountryMapper {
35     List<Country> selectByPageNumSize(User user);
36 }
37 //当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
38 List<Country> list = countryMapper.selectByPageNumSize(user);
39 
40 //第六种,ISelect 接口方式
41 //jdk6,7用法,创建接口
42 Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
43     @Override
44     public void doSelect() {
45         countryMapper.selectGroupBy();
46     }
47 });
48 //jdk8 lambda用法
49 Page<Country> page = PageHelper.startPage(1, 10).doSelectPage(()-> countryMapper.selectGroupBy());
50 
51 //也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
52 pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
53     @Override
54     public void doSelect() {
55         countryMapper.selectGroupBy();
56     }
57 });
58 //对应的lambda用法
59 pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> countryMapper.selectGroupBy());
60 
61 //count查询,返回一个查询语句的count数
62 long total = PageHelper.count(new ISelect() {
63     @Override
64     public void doSelect() {
65         countryMapper.selectLike(country);
66     }
67 });
68 //lambda
69 total = PageHelper.count(()->countryMapper.selectLike(country));

5、安全调用:

PageHelper 方法使用了静态的 ThreadLocal 参数,分页参数和线程是绑定的。

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

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

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

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

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

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

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

这种写法就能保证安全。

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

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

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

6、参考资料:

https://pagehelper.github.io/docs/howtouse/

https://blog.csdn.net/qq_33609401/article/details/83749083

原文地址:https://www.cnblogs.com/laoxia/p/11430021.html