mybatisplus PageHelper

PageHelper用于查询语句分页,让分页更简单、代码更优雅。发火如果硬是要纠结效率与资源,那您倒是直接手写BaseDao哇....

集成mybatis-plus,代码中添加分页相关配置

    /**
     * mybatis-plus分页插件<br>
     * 文档:http://mp.baomidou.com<br>
     */
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor page = new PaginationInterceptor();
        page.setDialectType("mysql");
        // 打开PageHelper localPage 模式
        page.setLocalPage(true);
        return page;
    }

这样就能使用PageHelper来分页了,当然要问了,为什么必须要手动设置打开呢?那就直接看源码咯~

直贴关键代码,具体源码请查阅:PaginationInterceptor.java

package com.baomidou.mybatisplus.plugins;

/**
 * <p>
 * 分页拦截器
 * </p>
 *
 * @author hubin
 * @Date 2016-01-23
 */
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class PaginationInterceptor implements Interceptor {
    /* 是否开启 PageHelper localPage 模式 */
    private boolean localPage = false;

    /**
     * Physical Pagination Interceptor for all the queries with parameter {@link org.apache.ibatis.session.RowBounds}
     */
    public Object intercept(Invocation invocation) throws Throwable {
        StatementHandler statementHandler = (StatementHandler) PluginUtils.realTarget(invocation.getTarget());
        MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);
        // 先判断是不是SELECT操作
        MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
        if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
            return invocation.proceed();
        }
        RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
        /* 不需要分页的场合 */
        if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
            // 本地线程分页
            if (localPage) {
                // 采用ThreadLocal变量处理的分页
                rowBounds = PageHelper.getPagination();
                if (rowBounds == null) {
                    return invocation.proceed();
                }
            } else {
                // 无需分页
                return invocation.proceed();
            }
        }
        // 针对定义了rowBounds,做为mapper接口方法的参数
        BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
        String originalSql = boundSql.getSql();
        Connection connection = (Connection) invocation.getArgs()[0];
        DBType dbType = StringUtils.isNotEmpty(dialectType) ? DBType.getDBType(dialectType) : JdbcUtils.getDbType(connection.getMetaData().getURL());
        if (rowBounds instanceof Pagination) {
            Pagination page = (Pagination) rowBounds;
            boolean orderBy = true;
            if (page.isSearchCount()) {
                SqlInfo sqlInfo = SqlUtils.getCountOptimize(sqlParser, originalSql);
                orderBy = sqlInfo.isOrderBy();
                this.queryTotal(overflowCurrent, sqlInfo.getSql(), mappedStatement, boundSql, page, connection);
                if (page.getTotal() <= 0) {
                    return invocation.proceed();
                }
            }
            String buildSql = SqlUtils.concatOrderBy(originalSql, page, orderBy);
            originalSql = DialectFactory.buildPaginationSql(page, buildSql, dbType, dialectClazz);
        } else {
            // support physical Pagination for RowBounds
            originalSql = DialectFactory.buildPaginationSql(rowBounds, originalSql, dbType, dialectClazz);
        }

		/*
         * <p> 禁用内存分页 </p>
         * <p> 内存分页会查询所有结果出来处理(这个很吓人的),如果结果变化频繁这个数据还会不准。</p>
		 */
        metaStatementHandler.setValue("delegate.boundSql.sql", originalSql);
        metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
        metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
        return invocation.proceed();
    }

    public void setLocalPage(boolean localPage) {
        this.localPage = localPage;
    }
}
关键地方已标红,在PaginationInterceptor中,是否开启 PageHelper localPage 模式,默认是关闭的,需要手动打开
    /* 是否开启 PageHelper localPage 模式 */
    private boolean localPage = false;
这货为啥不是默认打开呢?查看PageHelper类可以发现,是基于ThreadLocal实现,了然。
public class PageHelper {

    // 分页本地线程变量
    private static final ThreadLocal<Pagination> LOCAL_PAGE = new ThreadLocal<>();

    /**
     * <p>
     * 获取分页
     * </p>
     *
     * @return
     */
    public static Pagination getPagination() {
        return LOCAL_PAGE.get();
    }

    /**
     * <p>
     * 设置分页
     * </p>
     *
     * @param page
     */
    public static void setPagination(Pagination page) {
        LOCAL_PAGE.set(page);
    }

好,接下来使用就方便了

            // 组装查询条件
            EntityWrapper<User> wrapper = new EntityWrapper<>();
            if (null != status) {
                wrapper.eq("status", status);
            }
            // 设置分页参数
            PageHelper.startPage(pageIndex, pageSize);
            // 执行查询
            List<User> platfProjects = UserMapper.selectList(wrapper);
            // 返回的分页参数
            Pagination pagination = PageHelper.getPagination();

就是这样~

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jc_

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值