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 }
这么写很不好看,而且没有必要。