Mybatis使用PageHelper插件实现自定义分页

2022-05-12 21:44:45 浏览数 (1)

一、前言

最近想使用mybatis实现分页功能,同时自定义分页查询语句,扩展pageHelper插件的分页功能,官网推荐的方式是通过引入pageHelper的maven依赖,进行配置,可以参考我之前这篇文章,这次想通过jar包形式引入,离线环境下整合分页功能。

mybatis基于pagehelper插件实现分页功能

二、实践

首先引入包,主要有下面这些,以maven配置形式提供出来,我们需要下载下面maven对应的jar包,否则分页最后会不生效。

(1)jsqlparser是sql解析工具。

代码语言:javascript复制
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-autoconfigure</artifactId>
    <version>1.2.5</version>
</dependency>
<dependency>
    <groupId>jsqlparser</groupId>
    <artifactId>com.jsqlparser</artifactId>
    <version>3.1</version>
</dependency>

pageHelper支持大多数数据库实现分页,在PageAutoDialect类下可以看到所有支持的数据库。有mysql,oracle等。

代码语言:javascript复制
    static {
        registerDialectAlias("hsqldb", HsqldbDialect.class);
        registerDialectAlias("h2", HsqldbDialect.class);
        registerDialectAlias("postgresql", HsqldbDialect.class);
        registerDialectAlias("phoenix", HsqldbDialect.class);
        registerDialectAlias("mysql", MySqlDialect.class);
        registerDialectAlias("mariadb", MySqlDialect.class);
        registerDialectAlias("sqlite", MySqlDialect.class);
        registerDialectAlias("oracle", OracleDialect.class);
        registerDialectAlias("db2", Db2Dialect.class);
        registerDialectAlias("informix", InformixDialect.class);
        registerDialectAlias("informix-sqli", InformixDialect.class);
        registerDialectAlias("sqlserver", SqlServerDialect.class);
        registerDialectAlias("sqlserver2012", SqlServer2012Dialect.class);
        registerDialectAlias("derby", SqlServer2012Dialect.class);
        registerDialectAlias("dm", OracleDialect.class);
    }

假如想自定义分页实现,只需要继承AbstractHelperDialect类,然后重写getPageSql方法即可。同时静态方法调用PageAutoDialect.registerDialectAlias()自定义方言,后面进行配置。比如我新定义了一个分页实现,达梦数据库和clickhouse数据库都可以通过他实现分页,如下。可以看出,重点是getPageSql方法,只需要在这里修改成自己数据库支持的分页查询语法就可以了。他会在查询sql语句中拼接分页语句。

代码语言:javascript复制
import com.github.pagehelper.Page;
import com.github.pagehelper.dialect.AbstractHelperDialect;
import com.github.pagehelper.page.PageAutoDialect;
import com.github.pagehelper.util.MetaObjectUtil;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

@Component
public class MYDialect extends AbstractHelperDialect  {

    static {
        PageAutoDialect.registerDialectAlias("mydb", MYDialect.class);
    }

    public MYDialect() {
    }



    @Override
    public Object processPageParameter(MappedStatement ms, Map<String, Object> paramMap, Page page, BoundSql boundSql, CacheKey pageKey) {
        paramMap.put(PAGEPARAMETER_FIRST, page.getStartRow());
        paramMap.put(PAGEPARAMETER_SECOND, page.getPageSize());
        //处理pageKey
        pageKey.update(page.getStartRow());
        pageKey.update(page.getPageSize());
        //处理参数配置
        if (boundSql.getParameterMappings() != null) {
            List<ParameterMapping> newParameterMappings = new ArrayList<ParameterMapping>();
            if (boundSql != null && boundSql.getParameterMappings() != null) {
                newParameterMappings.addAll(boundSql.getParameterMappings());
            }
            if (page.getStartRow() == 0) {
                newParameterMappings.add(new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_SECOND, Integer.class).build());
            } else {
                newParameterMappings.add(new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_FIRST, Integer.class).build());
                newParameterMappings.add(new ParameterMapping.Builder(ms.getConfiguration(), PAGEPARAMETER_SECOND, Integer.class).build());
            }
            MetaObject metaObject = MetaObjectUtil.forObject(boundSql);
            metaObject.setValue("parameterMappings", newParameterMappings);
        }
        return paramMap;
    }

    @Override
    public String getPageSql(String sql, Page page, CacheKey pageKey) {
        StringBuilder sqlBuilder = new StringBuilder(sql.length()   14);
        sqlBuilder.append(sql);
        if (page.getStartRow() == 0) {
            sqlBuilder.append(" LIMIT ? ");
        } else {
            sqlBuilder.append(" LIMIT ?, ? ");
        }
        pageKey.update(page.getPageSize());
        return sqlBuilder.toString();
    }
}

最后在配置文件中进行配置,如下

(1)helper-dialect:分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。你可以配置helper-dialect属性来指定分页插件使用哪种方言。

(2)reasonable:分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。

(3)supportMethodsArguments:支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。

(4)params:为了支持startPage(Object params)方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable,不配置映射的用默认值,pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero=pageSizeZero。

代码语言:javascript复制
pagehelper.helper-dialect=mydb
pagehelper.reasonable=true
pagehelper.supportMethodsArguments=true
pagehelper.params = count=countSql

这样启动以后,在需要分页的查询方法之前调用一下下面方法就可以对查询实现分页。

代码语言:javascript复制
PageHelper.startPage(Integer.valueOf(pageNum), Integer.valueOf(pageSize));

三、参考

1、如何使用分页插件

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

2、项目代码地址:

https://github.com/xujiankang6/study/tree/main/mybatis-fenye

四、总结

以上就是实现PageHelper插件实现自定义分页所有内容,希望能够帮到大家,可以git下载下来,参考一下,下面地址,切换到fenye-mybatis分支

0 人点赞