归档
总说明
源码仓库: https://github.com/pagehelper/Mybatis-PageHelper 克隆:git clone https://github.com/pagehelper/Mybatis-PageHelper.git
切分支(tag):git checkout master
JDK: 17
单元测试
参考:com.github.pagehelper.test.reasonable.PageTest
@Test
public void testMapperWithStartPage ( ) {
SqlSession sqlSession = MybatisReasonableHelper . getSqlSession ( ) ;
UserMapper userMapper = sqlSession. getMapper ( UserMapper . class ) ;
try {
PageHelper . startPage ( 4 , 50 ) ;
List < User > list = userMapper. selectAll ( ) ;
PageInfo < User > page = new PageInfo < User > ( list) ;
}
}
hsqldb\mybatis-config-reasonable.xml
< configuration>
< plugins>
< plugin interceptor = " com.github.pagehelper.PageInterceptor" >
< property name = " reasonable" value = " true" />
</ plugin>
</ plugins>
</ configuration>
< mapper namespace = " com.github.pagehelper.mapper.UserMapper" >
< select id = " selectAll" resultType = " User" >
select * from user order by id -- comment
</ select>
</ mapper>
原理
开启分页
com.github.pagehelper.PageHelper
public class PageHelper extends PageMethod implements Dialect , BoundSqlInterceptor. Chain {
@Override
public void afterAll ( ) {
AbstractHelperDialect delegate = autoDialect. getDelegate ( ) ;
if ( delegate != null ) {
delegate. afterAll ( ) ;
autoDialect. clearDelegate ( ) ;
}
clearPage ( ) ;
}
public static void clearPage ( ) {
LOCAL_PAGE . remove ( ) ;
}
}
com.github.pagehelper.page.PageMethod
public abstract class PageMethod {
protected static final ThreadLocal < Page > LOCAL_PAGE = new ThreadLocal < Page > ( ) ;
protected static boolean DEFAULT_COUNT = true ;
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, null , null ) ;
}
public static < E > Page < E > startPage ( int pageNum, int pageSize, boolean count, Boolean reasonable, Boolean pageSizeZero) {
Page < E > page = new Page < E > ( pageNum, pageSize, count) ;
page. setReasonable ( reasonable) ;
page. setPageSizeZero ( pageSizeZero) ;
. . .
setLocalPage ( page) ;
return page;
}
public static void setLocalPage ( Page page) {
LOCAL_PAGE . set ( page) ;
}
}
拦截器
com.github.pagehelper.PageInterceptor
@Intercepts ( {
@Signature ( type = Executor . class , method = "query" , args = {
MappedStatement . class , Object . class , RowBounds . class , ResultHandler . class
} ) ,
@Signature ( type = Executor . class , method = "query" , args = {
MappedStatement . class , Object . class , RowBounds . class , ResultHandler . class , CacheKey . class , BoundSql . class
} ) ,
} )
public class PageInterceptor implements Interceptor {
private volatile Dialect dialect;
private String default_dialect_class = "com.github.pagehelper.PageHelper" ;
@Override
public void setProperties ( Properties properties) {
. . .
String dialectClass = . . . default_dialect_class;
Dialect tempDialect = ClassUtil . newInstance ( dialectClass, properties) ;
tempDialect. setProperties ( properties) ;
. . .
dialect = tempDialect;
}
@Override
public Object intercept ( Invocation invocation) throws Throwable {
try {
Object [ ] args = invocation. getArgs ( ) ;
MappedStatement ms = ( MappedStatement ) args[ 0 ] ;
. . .
if ( args. length == 4 ) {
. . .
} else {
. . .
}
. . .
List resultList;
if ( ! dialect. skip ( ms, parameter, rowBounds) ) {
. . .
if ( dialect. beforeCount ( ms, parameter, rowBounds) ) {
. . .
else {
Long count = count ( executor, ms, parameter, rowBounds, null , boundSql) ;
if ( ! dialect. afterCount ( count, parameter, rowBounds) ) {
return dialect. afterPage ( new ArrayList ( ) , parameter, rowBounds) ;
}
}
}
resultList = ExecutorUtil . pageQuery (
dialect, executor, ms, parameter, rowBounds, resultHandler, boundSql, cacheKey
) ;
. . .
} . . .
return dialect. afterPage ( resultList, parameter, rowBounds) ;
} finally {
if ( dialect != null ) {
dialect. afterAll ( ) ;
}
}
}
}
总结
原理总体较简单 只在一个拦截器里处理(统计与数据查询) 最后返回 Page<T>
封装集合类