首先是写的代码
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中也就有值了