package com.dk.common.infrastructure.util; import com.alibaba.fastjson.JSON; import org.apache.ibatis.builder.StaticSqlSource; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.SqlSource; 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.scripting.defaults.DefaultParameterHandler; import org.apache.ibatis.scripting.defaults.RawSqlSource; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.springframework.stereotype.Component; import java.beans.BeanInfo; import java.beans.Introspector; import java.beans.PropertyDescriptor; import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.HashMap; import java.util.LinkedHashMap; import java.util.Map; /** * @author 沈博 * @date_time 2022年3月11日14:10:19 * @description 拦截方法添加国际化参数 (目前有点小问题 url拼参数的无法添加) * TODO selectById的非Map类型参数的暂不支持 待修改 */ @Component @Intercepts({ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})}) public class MybatisSqlIntercept implements Interceptor { public static String I18N = ""; public static Integer cpId = 0; @Override public Object intercept(Invocation invocation) throws Throwable { Object[] args = invocation.getArgs(); Object[] args2 = new Object[4]; args2[3] = args[3]; args2[2] = args[2]; if ((args[1] instanceof Map || args[1] instanceof Object) && checkType(args)) { Object argsNo2 = args[1]; //map类型,对于数字的转换,如果直接转,Long给转成了Integer Map argsNo2Map = null; if (args[1] instanceof Map) { argsNo2Map = new HashMap<>(); for (String key : ((Map) args[1]).keySet()) { argsNo2Map.put(key, ((Map) args[1]).get(key)); } } else { try { argsNo2Map = convertBeanToMap(args[1]); } catch (Exception ignored) { } } if (argsNo2Map != null) { argsNo2Map.put("i18n", I18N); if(cpId != 0){ argsNo2Map.put("cpId", cpId); } args2[1] = argsNo2Map; } } else { args2[1] = args[1]; //TODO 在此添加单参数的逻辑 做法是获取父类的方法的参数名 然后把单参数转成Map传给xml } args2[0] = args[0]; Invocation newInvocation = new Invocation( invocation.getTarget(), invocation.getMethod(), args2 ); // MappedStatement mappedStatement = (MappedStatement) args[0]; // String cmdType = mappedStatement.getSqlCommandType().name(); // if ("update".equalsIgnoreCase(cmdType)) { // List> objList = SpringUtils.getBean(PlugMapper.class) // } return newInvocation.proceed(); } private boolean checkType(Object[] args) { return !(args[1] instanceof Long) && !(args[1] instanceof Integer) && !(args[1] instanceof String); } /** * @desc : 实体转Map * @author : 洪旭东 * @date : 2023-03-27 11:18 */ public Map convertBeanToMap(Object obj) { if (obj == null) { return null; } Map map = new HashMap<>(16); try { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); PropertyDescriptor[] propertyDescriptors = beanInfo.getPropertyDescriptors(); for (PropertyDescriptor property : propertyDescriptors) { String key = property.getName(); // 过滤class属性 if (!key.equals("class")) { // 得到property对应的getter方法 Method getter = property.getReadMethod(); Object value = getter.invoke(obj); if (null != value) { map.put(key, value); } } } } catch (Exception ignore) { return null; } return map; } }