• 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

  • 相关阅读:
    分层开发的优势
    分层开发的特点
    三层开发遵循的原则
    为什么需要分层
    什么是JNDI
    为什么需要JavaBean
    连接池中的连接对象是由谁创建的呢?
    什么是连接池技术
    为什么使用连接池?(为什么要使用JNDI)
    Servlet加载
  • 原文地址:https://www.cnblogs.com/laoxia/p/11430021.html
Copyright © 2020-2023  润新知