com.hhao.common.mybatis.page.interceptor.PageInterceptor Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2008-2024 wangsheng
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* https://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hhao.common.mybatis.page.interceptor;
import com.hhao.common.mybatis.page.PageInfo;
import com.hhao.common.mybatis.page.PageInfoWithCountMappedStatement;
import com.hhao.common.mybatis.page.PageMetaData;
import com.hhao.common.mybatis.page.executor.MultiQueriesDynamicPageExecutor;
import com.hhao.common.mybatis.page.executor.SingleQueryDynamicPageExecutor;
import com.hhao.common.mybatis.page.executor.SingleQueryStaticPageExecutor;
import org.apache.ibatis.binding.MapperMethod;
import org.apache.ibatis.executor.Executor;
import com.hhao.common.log.LoggerFactory;
import com.hhao.common.log.Logger;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.mybatis.dynamic.sql.select.render.SelectStatementProvider;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Properties;
/**
* MyBatis拦截器
*
* @author Wang
* @since 1.0.0
*/
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})
})
public class PageInterceptor implements Interceptor {
private static final Logger log = LoggerFactory.getLogger(PageInterceptor.class);
private final String DEFAULT_PAGE_INFO_PARAM_NAME = PageMetaData.PAGE_INFO_PARAM_NAME;
private Properties properties;
@Override
public Object intercept(Invocation invocation) throws Throwable {
PageInfo pageInfo=getPageInfo(invocation);
if (pageInfo!=null){
//pageExecutor使用的优先级
//1、pageInfo中自定义
//2、如果是PageInfoWithCount,优先使用指定的CountMappedStatementId
//3、如果开启多查询支持,优先使用MultiQueriesDynamicPageExecutor
//4、使用SingleQueryDynamicPageExecutor
if (pageInfo.getPageExecutor()==null) {
if (pageInfo instanceof PageInfoWithCountMappedStatement) {
if (((PageInfoWithCountMappedStatement) pageInfo).getCountMappedStatementId() != null) {
pageInfo.setPageExecutor(new SingleQueryStaticPageExecutor());
}
}else if (PageMetaData.SUPPORT_MULTI_QUERIES){
pageInfo.setPageExecutor(new MultiQueriesDynamicPageExecutor());
}else{
pageInfo.setPageExecutor(new SingleQueryDynamicPageExecutor());
}
}
log.info("Use PageExecutor:" + pageInfo.getPageExecutor());
Object result =pageInfo.getPageExecutor().execute(invocation,pageInfo);
return result;
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Interceptor.super.plugin(target);
}
@Override
public void setProperties(Properties properties) {
this.properties=properties;
}
/**
* Gets page info.
*
* @param invocation the invocation
* @return the page info
*/
protected PageInfo getPageInfo(Invocation invocation) {
Object[] args = invocation.getArgs();
MappedStatement mappedStatement = (MappedStatement) args[0];
Object parameter = args[1];
//获取PageInfo参数,如果未获取,则不支持
return getPageInfo(parameter);
}
/**
* 获取PageInfo参数
*
* @param parameter the parameter
* @return page info
*/
protected PageInfo getPageInfo(Object parameter) {
PageInfo pageInfo = null;
//针对动态SQL的SelectStatementProvider
if (parameter instanceof SelectStatementProvider) {
Map parameters=((SelectStatementProvider) parameter).getParameters();
//先按名称查PageInfo参数
pageInfo = (PageInfo) ((SelectStatementProvider) parameter).getParameters().get(DEFAULT_PAGE_INFO_PARAM_NAME);
//再按类型查PageInfo参数
if (pageInfo==null){
for(Map.Entry entry:parameters.entrySet()){
if (entry.getValue() instanceof PageInfo){
pageInfo=(PageInfo)entry.getValue();
break;
}
}
}
} else if (parameter instanceof MapperMethod.ParamMap) {
//针对Mapper传参
//先按名称
MapperMethod.ParamMap paramMap = (MapperMethod.ParamMap) parameter;
try {
pageInfo = (PageInfo) paramMap.get(DEFAULT_PAGE_INFO_PARAM_NAME);
} catch (Exception e) {
}
//再按类型
if (pageInfo==null){
for(Object key:paramMap.keySet()){
Object value=paramMap.get(key);
if (value instanceof PageInfo){
pageInfo=(PageInfo) value;
break;
}
}
}
}
return pageInfo;
}
/**
* 判断返回值是否是PageInfo
*
* @param invocation
* @return
*/
private boolean hasPageInfoReturnType(Invocation invocation) {
Class> returnType=getReturnType(invocation);
return PageInfo.class.isAssignableFrom(returnType);
}
private Class> getReturnType(Invocation invocation) {
try {
Method method = invocation.getMethod();
return method.getReturnType();
} catch (Exception e) {
throw new RuntimeException("Failed to get return type", e);
}
}
}