Commit e2fa5b9a by hulei

增加Mybatis拦截器自动添加SettleContext中的etyextkey,etgextkey

parent 6ca280b9
package com.brilliance.isc.support;
import cn.hutool.core.util.StrUtil;
import com.brilliance.isc.bo.Etg;
import com.brilliance.isc.bo.Ety;
import com.brilliance.isc.common.context.SettleContext;
import com.brilliance.isc.common.context.SettleSession;
import com.github.pagehelper.util.ExecutorUtil;
import com.github.pagehelper.util.MetaObjectUtil;
import org.apache.ibatis.builder.annotation.ProviderSqlSource;
import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
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.reflection.MetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.Map;
/**
* 拦截查询语句,自动获取ETY,ETG信息加入SQL参数列表,
* SQL语句中可直接通过固定名称获取。
* _etyextkey etyextkey绑定属性名
* _etgextkey etgextkey绑定属性名
* @Auth hulei
* @DATE 2024/11/01
*/
@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 CustomInterceptor implements Interceptor {
private static final Logger logger = LoggerFactory.getLogger(CustomInterceptor.class);
@Override
public Object intercept(Invocation invocation) throws Throwable {
if(!checkSession()){
return invocation.proceed();
}
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) {
//4 个参数时
boundSql = ms.getBoundSql(parameter);
cacheKey = executor.createCacheKey(ms, parameter, rowBounds, boundSql);
} else {
//6 个参数时
cacheKey = (CacheKey) args[4];
boundSql = (BoundSql) args[5];
}
args[1] = processParameterObject(ms,parameter,boundSql,cacheKey);
return invocation.proceed();
}
public Object processParameterObject(MappedStatement ms, Object parameterObject, BoundSql boundSql, CacheKey pageKey) {
//处理参数
Map<String, Object> paramMap = null;
if (parameterObject == null) {
paramMap = new HashMap<>();
} else if (parameterObject instanceof Map) {
//解决不可变Map的情况
paramMap = new HashMap<>();
paramMap.putAll((Map) parameterObject);
} else {
paramMap = new HashMap<>();
// sqlSource为ProviderSqlSource时,处理只有1个参数的情况
if (ms.getSqlSource() instanceof ProviderSqlSource) {
String[] providerMethodArgumentNames = ExecutorUtil.getProviderMethodArgumentNames((ProviderSqlSource) ms.getSqlSource());
if (providerMethodArgumentNames != null && providerMethodArgumentNames.length == 1) {
paramMap.put(providerMethodArgumentNames[0], parameterObject);
paramMap.put("param1", parameterObject);
}
}
//动态sql时的判断条件不会出现在ParameterMapping中,但是必须有,所以这里需要收集所有的getter属性
//TypeHandlerRegistry可以直接处理的会作为一个直接使用的对象进行处理
boolean hasTypeHandler = ms.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass());
MetaObject metaObject = MetaObjectUtil.forObject(parameterObject);
//需要针对注解形式的MyProviderSqlSource保存原值
if (!hasTypeHandler) {
for (String name : metaObject.getGetterNames()) {
paramMap.put(name, metaObject.getValue(name));
}
}
//下面这段方法,主要解决一个常见类型的参数时的问题
if (boundSql.getParameterMappings() != null && boundSql.getParameterMappings().size() > 0) {
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
String name = parameterMapping.getProperty();
if (paramMap.get(name) == null) {
if (hasTypeHandler
|| parameterMapping.getJavaType().equals(parameterObject.getClass())) {
paramMap.put(name, parameterObject);
break;
}
}
}
}
}
return processEtyEtgParameter(ms, paramMap, boundSql, pageKey);
}
// public void processAnnotation(MappedStatement ms){
// int lastDotIdx = ms.getId().lastIndexOf(".");
// String mapperName = ms.getId().substring(0,lastDotIdx);
// String methodName = ms.getId().substring(lastDotIdx+1);
// }
public static final String _ETY_PARAMETER_KEY = "_etyextkey";
public static final String _ETG_PARAMETER_KEY = "_etgextkey";
public Object processEtyEtgParameter(MappedStatement ms, Map<String, Object> paramMap, BoundSql boundSql, CacheKey pageKey) {
SettleSession session = SettleContext.getUserSession();
Ety ety = session.getEty();
Etg etg = session.getEtg();
paramMap.put(_ETY_PARAMETER_KEY, ety.getExtkey());
paramMap.put(_ETG_PARAMETER_KEY, etg.getExtkey());
//处理pageKey
pageKey.update(ety);
pageKey.update(etg);
return paramMap;
}
/**
* 检查SettleSession中是否有对应的ETY,ETG信息
* @return
*/
public boolean checkSession(){
SettleSession session = SettleContext.getUserSession();
if(session == null){
return false;
}
if(session.getEty() == null && session.getEtg() == null){
return false ;
}
if(StrUtil.isEmpty(session.getEty().getExtkey()) && StrUtil.isEmpty(session.getEtg().getExtkey())){
return false;
}
return true;
}
}
package com.brilliance.isc.support;
import org.apache.ibatis.plugin.Interceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class MyBatisConfig {
@Bean
public Interceptor customInterceptor() {
return new CustomInterceptor();
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment