PageHelper怎么把查询到的数值插入到Page类的

本文通过代码示例探讨了如何使用PageHelper在Lambda表达式中将查询结果存入Page类。通过分析ISelect接口、Page类、PageMethod类以及PageInterceptor拦截器的工作原理,揭示了查询数据如何在运行时被注入Page类并转化为PageInfo。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先是写的代码
在这里插入图片描述
lambda表达式写法:
在这里插入图片描述

@Service
public class SectionService {
    @Autowired
    private SectionMapper sectionMapper;

    public List<Section> getLimit(int start,int limit){
        PageInfo<Section> pageInfo = PageHelper.startPage(start, limit).doSelectPageInfo(() -> sectionMapper.findAll());
        return pageInfo.getList();
    }
}

来看一下一些主要类
先看Iselect类

public interface ISelect {
    void doSelect();
}

再来看一下Page类

public class Page<E> extends ArrayList<E> implements Closeable {
 public <E> PageInfo<E> doSelectPageInfo(ISelect select) {
        select.doSelect();
        return this.toPageInfo();
    }
    
 public PageInfo<E> toPageInfo() {
        PageInfo<E> pageInfo = new PageInfo(this);
        return pageInfo;
    }
}

我看到这行代码就很疑惑,返回void,并没有赋值,
怎么this(也就是这个page类)中就包含了查询到的结果呢

先了解一下这个
在这里插入图片描述

首来看一下PageMethod类中的部分代码

	public abstract class PageMethod {
	//PageMethod 类中含了一个本地线程LOCAL_PAGE 
	//Threadlocal而是一个线程内部的存储类,可以在指定线程内存储数据,数据存储以后,只有指定线程可以得到存储数据
    protected static final ThreadLocal<Page> LOCAL_PAGE = new ThreadLocal();
    }
    protected static void setLocalPage(Page page) {
        LOCAL_PAGE.set(page);
    }
    public static <E> Page<E> startPage(Object params) {
        Page<E> page = PageObjectUtil.getPageFromObject(params, true);
        Page<E> oldPage = getLocalPage();
        if (oldPage != null && oldPage.isOrderByOnly()) {
            page.setOrderBy(oldPage.getOrderBy());
        }
        setLocalPage(page);
        return page;
    }
    //我们刚才使用了这个方法,此方法是设置开始查询页数和一页的数量
    public static <E> Page<E> startPage(int pageNum, int pageSize) {
        return startPage(pageNum, pageSize, DEFAULT_COUNT);
    }
	//接下来调用这个方法
    public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count) {
        return startPage(pageNum, pageSize, count, (Boolean)null, (Boolean)null);
    }
    然后调用这个方法
    public static <E> Page<E> startPage(int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {
        Page<E> page = new Page(pageNum, pageSize, count);
        page.setReasonable(reasonable);
        page.setPageSizeZero(pageSizeZero);
        Page<E> oldPage = getLocalPage();
        if (oldPage != null && oldPage.isOrderByOnly()) {
            page.setOrderBy(oldPage.getOrderBy());
        }
        //在这里新建一个Page,把它存在了本地线程里
        setLocalPage(page);
        return page;
    }

好了,接下来就有知识了,当运行时,会触发PageInterceptor拦截器,即

public class PageInterceptor implements Interceptor {
//就会执行此方法
public Object intercept(Invocation invocation) throws Throwable {
        Object var16;
        try {
            Object[] args = invocation.getArgs();
            MappedStatement ms = (MappedStatement)args[0];
            Object parameter = args[1];
            RowBounds rowBounds = (RowBounds)args[2];
            ResultHandler resultHandler = (ResultHandler)args[3];
            Executor executor = (Executor)invocation.getTarget();
            CacheKey cacheKey;
            BoundSql boundSql;
            if (args.length == 4) {
                boundSql = ms.getBoundSql(parameter);
                cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
            } else {
                cacheKey = (CacheKey)args[4];
                boundSql = (BoundSql)args[5];
            }

            this.checkDialectExists();
            List resultList;
            if (!this.dialect.skip(ms, parameter, rowBounds)) {
                if (this.dialect.beforeCount(ms, parameter, rowBounds)) {
                    Long count = this.count(executor, ms, parameter, rowBounds, resultHandler, boundSql);
                    if (!this.dialect.afterCount(count, parameter, rowBounds)) {
                        Object var12 = this.dialect.afterPage(new ArrayList(), parameter, rowBounds);
                        return var12;
                    }
                }

                resultList = ExecutorUtil.pageQuery(this.dialect, executor, ms, parameter, rowBounds, resultHandler, boundSql, cacheKey);
            } else {
                resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
            }
//上方的resultList就是经过组装的sql语句查询出的结果,之后执行下面这行
            var16 = this.dialect.afterPage(resultList, parameter, rowBounds);
        } finally {
            if (this.dialect != null) {
                this.dialect.afterAll();
            }

        }

        return var16;
    }
}

在这里插入图片描述

再来看一下PageHelper类

	public class PageHelper extends PageMethod implements Dialect {private PageParams pageParams;
    private PageAutoDialect autoDialect;
    //执行到这个方法
	public Object afterPage(List pageList, Object parameterObject, RowBounds rowBounds) {
        AbstractHelperDialect delegate = this.autoDialect.getDelegate();
        return delegate != null ? delegate.afterPage(pageList, parameterObject, rowBounds) : pageList;
    }

getDelegate()

public class PageAutoDialect {
	private AbstractHelperDialect delegate;
	public AbstractHelperDialect getDelegate() {
        return this.delegate != null ? this.delegate : (AbstractHelperDialect)this.dialectThreadLocal.get();
    }
 }

//进入AbstractHelperDialect类看一下

public abstract class AbstractHelperDialect extends AbstractDialect implements Constant {
//在PageHelper中会调用这个方法
	public Object afterPage(List pageList, Object parameterObject, RowBounds rowBounds) {
	//获取本地线程中的page
        Page page = this.getLocalPage();
        if (page == null) {
            return pageList;
        } else {
        //如果page存在,则把pageList结果插入到page中,因为page继承了ArrayList,所以就是在这里赋值的
            page.addAll(pageList);
            if (!page.isCount()) {
                page.setTotal(-1L);
            } else if (page.getPageSizeZero() != null && page.getPageSizeZero() && page.getPageSize() == 0) {
                page.setTotal((long)pageList.size());
            } else if (page.isOrderByOnly()) {
                page.setTotal((long)pageList.size());
            }

            return page;
        }
    }
}

所以最终是执行 了AbstractHelperDialect类中的afterPage方法,把值插入进去的

之后page类的toPageInfo方法返回给一个传入本身的构造方法
生成一个PageInfo,PageInfo中也就有值了

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值