Mybatis paging framework-PageHelper


This article is used to summarize the use of PageHelper paging plug-in. PageHelper is a paging plug-in for Mybatis. Its implementation principle is based on Mybatis's interceptor QueryInterceptor. By intercepting sql queries, sql is enhanced and transformed. In fact, this idea They abound. For example, MP's paging plug-in also has this idea, and the Interceptor in various components also has this idea. Here is a summary of common usage.

1. Basic use of PageHelper

Commonly used paging components in Java are physical paging, and there is basically no logical paging. PageHelper is also a physical paging plugin. Physical paging is to use SQL to directly page the data. During logical paging, all the data is found and then paging is performed. In this way, when the amount of data is large, the content cannot be held at all (unless the system is relatively small). Therefore, physical paging plug-ins such as PageHelper are used when actually used.

1.Introduce jar package

There is nothing to say. Use maven to introduce the jar package. The official documentation recommends using the latest version of the jar package. Here you can check the latest version through the official website, as shown below: Article writing time: 2023-09-22 PageHelper latest
version :
5.3 . 3
Official website address : PageHelper official website
This article uses Springboot version : 2.4.4
Insert image description here

        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.3.3</version>
            <!-- 分页插件只会在编译期有用,这里可以声明为compile -->
            <scope>compile</scope>
        </dependency>

2. Configure conifg

To use PageHelper, you must configure its paging interceptor PageInterceptor. This paging interceptor is the key to using PageHelper to implement paging. The most important point is that we need to specify the dialect of the database (in layman's terms, it is the type of database). Because the paging implementation of different databases is different, we need to specify the database so that PageHelper can help us dynamically adjust SQL. It has the following configuration items.
Note: If you do not configure this official document, you can also identify the database dialect by yourself. However, I found that paging cannot take effect without configuring it. I have verified that both versions 5.3.3 and 5.1.11 cannot paginate normally, so I still add this. Best configuration

import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;

/**
 * @author pcc
 * 这是分页插件PageHelper的配置信息
 * 使用PageHelper的原因是MP的分页对于多表分页查询和自定义查询的分页支持不够优秀
 */
@Configuration
public class PageHelperConfig {
    
    

    /**
     * 可能存在多个连接工厂,是允许这么注入的
     */
    @Resource
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @PostConstruct
    public void initConfig(){
    
    
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }
}

All the configuration is completed above, and it is actually very simple and easy to use.

3. Test use

It is actually very simple to use, but you need to pay attention to the following two points:

    1. Only the first Mybatis query (Select) method immediately following the PageHelper.startPage method will be paged.
    1. Pagination with for update statement is not supported
    1. Using the following paging method, the result returned by the query method must be List<T>, because the object returned by PageHelper paging is a Page of ArrayList type.

Here is the paging code:

    /**
     * 使用 PageHelper进行分页
     * @param tbTaskItemsVO 入参
     * @return 返回
     */
    @PostMapping("/getTaskItemsPage2")
    public PageInfo<TbTaskItems> getTaskItems2(TbTaskItemsVO tbTaskItemsVO){
    
    
        PageHelper.startPage(tbTaskItemsVO.getPageNum(),tbTaskItemsVO.getPageSize());
        List<TbTaskItems> itemsList = iTbTaskItemsService.queryItems();
        PageInfo<TbTaskItems> pageInfo = new PageInfo<>(itemsList);
        return pageInfo;
    }

The above code can implement paging normally:
Insert image description here
you can see that the key information of our paging is correct. It is very simple to use, but there are still a few points that need to be explained:

  • 1.PageHelper.startPage passes in pageNum, pageSize
  • 2. The return type of the query method (here is iTbTaskItemsService.queryItems) must be ArrayList<T> or its parent class. Although the return value received by List is used here, it looks no different from the original method. In fact, the return value of iTbTaskItemsService.queryItems here is The parameter is actually Page. Because Page is a subclass of ArrayList, it can be written like this. Therefore, when defining our method, we need to define that the return type is ArrayList or its parent class.

2. Various uses of PageHelper

In actual work scenarios, it is basically enough to use the usage in the first section. Here we will expand and talk about other common ways of writing PageHelper. The first few below are more commonly used writing methods. In addition to these, it can also support passing in RowBound, or writing query methods to declare paging parameters. However, these two are not commonly used and will not be discussed. If you are interested, you can read the official documentation: PageHelper
official document

1. Use PageHelper.startPage to pass in the object

The method used here is not much different from the first method. The object passed in is the overloaded method of the first method. The object passed in must have two parameters, pageNum and pageSize, and cannot be empty, so that paging can be done normally.

// 对于上面的写法就动如下代码即可:
PageHelper.startPage(tbTaskItemsVO);

2. Do not use PageHelper.startPage, but use PageHelper.offsetPage

The meaning of this writing method and the above PageHelper.startPage(offSet,limit) is to start from the subscript of offSet and get the limit data. This kind of paging requires us to calculate, which is a little more troublesome than the first one.

PageHelper.startPage(pageNum*PageSize,PageSize);

3. Use Lambda for pagination

PageHelper also supports the way of writing lambda in Java8. As long as it supports Java8, it will also support the way of writing anonymous inner classes. Here we only show the way of writing Java8. There is no difference in Java7.

    /**
     * 使用 PageHelper进行分页
     * @param tbTaskItemsVO 入参
     * @return 返回
     */
    @PostMapping("/getTaskItemsPage2")
    public PageInfo<TbTaskItems> getTaskItems2(TbTaskItemsVO tbTaskItemsVO){
    
    
    
        PageInfo<TbTaskItems> objectPageInfo = PageHelper.startPage(tbTaskItemsVO).doSelectPageInfo(() -> {
    
    
            iTbTaskItemsService.queryItems();
        });
        return objectPageInfo;
    }

4. Paginate directly without using PageHelper

This way of writing requires adding a PageInterceptor configuration item before it can be supported. It is not supported by default. This way of writing is the simplest and will prevent the code writer from seeing any traces of paging. However, this is not good and can easily be ignored. , but this way of writing is the most concise.

  • 1. Add new configuration items
// 配置supportMethodsArguments=true
// 分页插件会从查询方法的参数值中寻找pageNum,pageSize进行分页,找到就可以进行分页
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Properties;

/**
 * @author pcc
 * 这是分页插件PageHelper的配置信息
 * 使用PageHelper的原因是MP的分页对于多表分页查询和自定义查询的分页支持不够优秀
 */
@Configuration
public class PageHelperConfig {
    
    

    /**
     * 可能存在多个连接工厂,是允许这么注入的
     */
    @Resource
    private List<SqlSessionFactory> sqlSessionFactoryList;

    @PostConstruct
    public void initConfig(){
    
    
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        // 支持自动分页,需要保证查询方法的对象中必须含有pageNum,pageSize
        properties.setProperty("supportMethodsArguments","true");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }
}
  • 2. The query method needs to be modified to pass an object or Map, but it must contain pageNum and pageSize.
    /**
     * 使用 PageHelper进行分页
     * @param tbTaskItemsVO 入参
     * @return 返回
     */
    @PostMapping("/getTaskItemsPage2")
    public PageInfo<TbTaskItems> getTaskItems2(TbTaskItemsVO tbTaskItemsVO){
    
    
        List<TbTaskItems> itemsList = iTbTaskItemsService.queryItems(tbTaskItemsVO);
        PageInfo<TbTaskItems> pageInfo = new PageInfo<>(itemsList);
        return pageInfo;
    }

5. Want to use the paging interface to query all data

A new configuration parameter needs to be added: pageSizeZero=true. After configuring this parameter, if you want to query all data, you only need to pass pageSize=0, and all data will be queried by default, but the Page information will still be returned.

// 只展示配置信息
public void initConfig(){
    
    
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        // 支持自动分页,需要保证查询方法的对象中必须含有pageNum,pageSize
        properties.setProperty("supportMethodsArguments","true");
        // 支持查询全部信息
        properties.setProperty("pageSizeZero","true");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }

There is no difference for other uses, so I won’t repeat the examples.

6. Enter the abnormal page number and also supports paging.

When entering an abnormal page number, paging can also be supported. You need to add configuration: reasonable=true. After adding this configuration, when pageNum<=0, the first page will be queried. If pageNum>the maximum page, the last page will be queried. Of course pageSize must have a value.

// 只展示配置信息
public void initConfig(){
    
    
        PageInterceptor pageInterceptor = new PageInterceptor();
        Properties properties = new Properties();
        // 设置数据源方言,使用mysql
        properties.setProperty("helperDialect","mysql");
        // 支持自动分页,需要保证查询方法的对象中必须含有pageNum,pageSize
        properties.setProperty("supportMethodsArguments","true");
        // 支持查询全部信息
        properties.setProperty("pageSizeZero","true");
        // 支持异常页码查询
        properties.setProperty("reasonable","true");
        
        pageInterceptor.setProperties(properties);
        sqlSessionFactoryList.forEach(factory ->factory.getConfiguration().addInterceptor(pageInterceptor));
    }

Guess you like

Origin blog.csdn.net/m0_46897923/article/details/133188854