This is the 16th day of my participation in the November Gwen Challenge. Check out the event details: The last Gwen Challenge 2021
In yesterday’s article, we covered the first five lines of the PageInterceptor code. Today we’ll look at PageInterceptor, the PageHelper interceptor.
The next line of code is:
Executor executor = (Executor) invocation.getTarget();
Copy the code
The Executor of the full path for org. Apache. Ibatis. Executor. Executor.
Executor is an Executor in Mybatis, which is an interface. Its inheritance structure relation in MyBatis can be expressed as follows:
Executor:
-BaseExecutor:
-SimpleExecutor
-ReuseExeCutor
-BatchExeCutor
-CachingExecutor
Copy the code
An Executor’s main jobs include:
- Processing cache;
- Get database connection;
- create
Statement
- Execute SQL statement
- Process SQL execution results
And from Executor, we find two Executor query methods:
public abstract <E> java.util.List<E> query(org.apache.ibatis.mapping.MappedStatement arg0, java.lang.Object arg1, org.apache.ibatis.session.RowBounds arg2, org.apache.ibatis.session.ResultHandler arg3, org.apache.ibatis.cache.CacheKey arg4, org.apache.ibatis.mapping.BoundSql arg5) throws java.sql.SQLException;
public abstract <E> java.util.List<E> query(org.apache.ibatis.mapping.MappedStatement arg0, java.lang.Object arg1, org.apache.ibatis.session.RowBounds arg2, org.apache.ibatis.session.ResultHandler arg3) throws java.sql.SQLException;
Copy the code
According to PageHelper:
The query method with more arguments is called internally by the query method with fewer arguments
However, look further back at the code for PageInterceptor in PageHelper:
Executor executor = (Executor) invocation.getTarget();
CacheKey cacheKey;
BoundSql boundSql;
// Only one entry will be entered due to logic
if (args.length == 4) {
//4 arguments
boundSql = ms.getBoundSql(parameter);
cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
} else {
//6 parameters
cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}
Copy the code
Where did the Args come from?
The interceptor method is the same as the one we used in PageHelper.
Object[] args = invocation.getArgs();
Copy the code
The author also implemented a query method that blocks the Executor6 parameters.
Furthermore, this confirms that interceptors actually intercept Executor’s Query methods, sometimes with four arguments, sometimes with six arguments.
The most important lines of the following code:
// Intercepting boundSql
if (dialect instanceof BoundSqlInterceptor.Chain) {
boundSql = ((BoundSqlInterceptor.Chain) dialect).doBoundSql(BoundSqlInterceptor.Type.ORIGINAL, boundSql, cacheKey);
}
List resultList;
// Call the method to determine whether paging is required, and return the result if not
if(! dialect.skip(ms, parameter, rowBounds)) {// Determine whether a count query is required
if (dialect.beforeCount(ms, parameter, rowBounds)) {
// Query the total number
Long count = count(executor, ms, parameter, rowBounds, null, boundSql);
// Process the total number of queries, return true to continue paging query, false directly return
if(! dialect.afterCount(count, parameter, rowBounds)) {// If the total number of queries is 0, an empty result is returned
return dialect.afterPage(newArrayList(), parameter, rowBounds); } } resultList = ExecutorUtil.pageQuery(dialect, executor, ms, parameter, rowBounds, resultHandler, boundSql, cacheKey); }else {
//rowBounds takes the parameter value and supports the default memory paging when not handled by the paging plug-in
resultList = executor.query(ms, parameter, rowBounds, resultHandler, cacheKey, boundSql);
}
Copy the code
After layer by layer judgment, when paging is needed, this is done:
resultList = ExecutorUtil.pageQuery(dialect, executor,
ms, parameter, rowBounds, resultHandler, boundSql, cacheKey);
Copy the code
This is the line of code that returns the result when paging is required. When you open the ExecutorUtil code, you can see that there is more or less an internal execution of various judgments, eventually executing executor.query. When is paging SQL inserted into the original SQL? So how does the code automatically change when paging?