MP升级3.5.4

This commit is contained in:
yulichang 2023-10-23 15:20:49 +08:00
parent c60e89ea79
commit 1ce8f68f29
20 changed files with 190 additions and 166 deletions

View File

@ -46,7 +46,13 @@
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId> <artifactId>mybatis-plus-extension</artifactId>
<version>3.5.3.2</version> <version>3.5.4</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.28</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
</dependencies> </dependencies>

View File

@ -2,10 +2,13 @@ package com.github.yulichang.adapter.base;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.List;
import java.util.function.Supplier; import java.util.function.Supplier;
import java.util.stream.Collectors;
/** /**
* @author yulichang * @author yulichang
@ -13,15 +16,32 @@ import java.util.function.Supplier;
*/ */
public interface ITableInfoAdapter { public interface ITableInfoAdapter {
boolean mpjHasLogic(TableInfo tableInfo); default boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isWithLogicDelete();
}
boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo); default boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.isPrimitive();
}
TableFieldInfo mpjGetLogicField(TableInfo tableInfo); default TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getLogicDeleteFieldInfo();
}
boolean mpjHasPK(TableInfo tableInfo); default boolean mpjHasPK(TableInfo tableInfo) {
return tableInfo.havePK();
}
Configuration mpjGetConfiguration(TableInfo tableInfo); default Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier); default Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return fieldInfo.getField();
}
default List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
return tableInfo.getOrderByFields().stream().map(f ->
new OrderFieldInfo(f.getColumn(), f.getType(), f.getSort())).collect(Collectors.toList());
}
} }

View File

@ -0,0 +1,35 @@
package com.github.yulichang.adapter.base.metadata;
import lombok.Data;
/**
* 兼容MP 3.5.4
* copy {@link com.baomidou.mybatisplus.core.metadata.OrderFieldInfo}
*
* @since 1.4.7
*/
@Data
public class OrderFieldInfo {
/**
* 字段
*/
private String column;
/**
* 排序类型
*/
private String type;
/**
* 排序顺序
*/
private short sort;
public OrderFieldInfo(String column, String type, short orderBySort) {
this.column = column;
this.type = type;
this.sort = orderBySort;
}
}

View File

@ -1,4 +1,4 @@
package com.github.yulichang.toolkit; package com.github.yulichang.adapter.base.tookit;
/** /**
* 版本工具类 * 版本工具类

View File

@ -1,12 +1,16 @@
package com.github.yulichang.adapter.v33x; package com.github.yulichang.adapter.v33x;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.github.yulichang.adapter.base.ITableInfoAdapter; import com.github.yulichang.adapter.base.ITableInfoAdapter;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.function.Supplier; import java.util.function.Supplier;
@ -16,6 +20,8 @@ import java.util.function.Supplier;
*/ */
public class TableInfoAdapterV33x implements ITableInfoAdapter { public class TableInfoAdapterV33x implements ITableInfoAdapter {
private static final boolean is330 = VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.3.0") == 0;
@Override @Override
public boolean mpjHasLogic(TableInfo tableInfo) { public boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isLogicDelete(); return tableInfo.isLogicDelete();
@ -45,6 +51,11 @@ public class TableInfoAdapterV33x implements ITableInfoAdapter {
@Override @Override
public Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) { public Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return supplier.get(); return is330 ? supplier.get() : ITableInfoAdapter.super.mpjGetField(fieldInfo, null);
}
@Override
public List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
throw new UnsupportedOperationException("不支持排序");
} }
} }

View File

@ -0,0 +1,25 @@
package com.github.yulichang.adapter.v3431;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.github.yulichang.adapter.base.ITableInfoAdapter;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author yulichang
* @since 1.4.7
*/
public class TableInfoAdapter3431 implements ITableInfoAdapter {
private static final boolean v = VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3") < 0;
@Override
public List<OrderFieldInfo> mpjGetOrderField(TableInfo tableInfo) {
return v ? null : tableInfo.getOrderByFields().stream().map(f ->
new OrderFieldInfo(f.getColumn(), f.getOrderByType(), f.getOrderBySort())).collect(Collectors.toList());
}
}

View File

@ -58,7 +58,7 @@
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId> <artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version> <version>3.5.4</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -67,7 +67,7 @@
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId> <artifactId>mybatis-plus-extension</artifactId>
<version>3.5.3.2</version> <version>3.5.4</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -1,9 +1,11 @@
package com.github.yulichang.adapter; package com.github.yulichang.adapter;
import com.baomidou.mybatisplus.core.MybatisPlusVersion; import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.github.yulichang.adapter.base.ITableInfoAdapter; import com.github.yulichang.adapter.base.ITableInfoAdapter;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.adapter.v33x.TableInfoAdapterV33x; import com.github.yulichang.adapter.v33x.TableInfoAdapterV33x;
import com.github.yulichang.adapter.v3431.TableInfoAdapter3431;
/** /**
* @author yulichang * @author yulichang
@ -15,10 +17,14 @@ public class AdapterHelper {
static { static {
String version = MybatisPlusVersion.getVersion(); String version = MybatisPlusVersion.getVersion();
if (StringUtils.isNotBlank(version) && version.startsWith("3.3.")) { if (VersionUtils.compare(version, "3.5.4") >= 0) {
adapter = new TableInfoAdapter();
} else if (VersionUtils.compare(version, "3.4.0") >= 0) {
adapter = new TableInfoAdapter3431();
} else if (VersionUtils.compare(version, "3.3.0") >= 0) {
adapter = new TableInfoAdapterV33x(); adapter = new TableInfoAdapterV33x();
} else { } else {
adapter = new TableInfoAdapter(); throw ExceptionUtils.mpe("MPJ需要MP版本3.3.0+当前MP版本%s", version);
} }
} }

View File

@ -1,12 +1,6 @@
package com.github.yulichang.adapter; package com.github.yulichang.adapter;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.github.yulichang.adapter.base.ITableInfoAdapter; import com.github.yulichang.adapter.base.ITableInfoAdapter;
import org.apache.ibatis.session.Configuration;
import java.lang.reflect.Field;
import java.util.function.Supplier;
/** /**
* @author yulichang * @author yulichang
@ -14,33 +8,4 @@ import java.util.function.Supplier;
*/ */
public class TableInfoAdapter implements ITableInfoAdapter { public class TableInfoAdapter implements ITableInfoAdapter {
@Override
public boolean mpjHasLogic(TableInfo tableInfo) {
return tableInfo.isWithLogicDelete();
}
@Override
public boolean mpjIsPrimitive(TableFieldInfo tableFieldInfo) {
return tableFieldInfo.isPrimitive();
}
@Override
public TableFieldInfo mpjGetLogicField(TableInfo tableInfo) {
return tableInfo.getLogicDeleteFieldInfo();
}
@Override
public boolean mpjHasPK(TableInfo tableInfo) {
return tableInfo.havePK();
}
@Override
public Configuration mpjGetConfiguration(TableInfo tableInfo) {
return tableInfo.getConfiguration();
}
@Override
public Field mpjGetField(TableFieldInfo fieldInfo, Supplier<Field> supplier) {
return fieldInfo.getField();
}
} }

View File

@ -15,7 +15,7 @@ import com.github.yulichang.adapter.v3431.AbstractMethodV3431;
import com.github.yulichang.method.*; import com.github.yulichang.method.*;
import com.github.yulichang.toolkit.MPJTableMapperHelper; import com.github.yulichang.toolkit.MPJTableMapperHelper;
import com.github.yulichang.toolkit.TableHelper; import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.VersionUtils; import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.toolkit.reflect.GenericTypeUtils; import com.github.yulichang.toolkit.reflect.GenericTypeUtils;
import lombok.Getter; import lombok.Getter;
import org.apache.ibatis.builder.MapperBuilderAssistant; import org.apache.ibatis.builder.MapperBuilderAssistant;
@ -38,9 +38,9 @@ import static java.util.stream.Collectors.toList;
* @author yulichang * @author yulichang
* @see DefaultSqlInjector * @see DefaultSqlInjector
*/ */
@Getter
public class MPJSqlInjector extends DefaultSqlInjector { public class MPJSqlInjector extends DefaultSqlInjector {
@Getter
private AbstractSqlInjector sqlInjector; private AbstractSqlInjector sqlInjector;
public MPJSqlInjector() { public MPJSqlInjector() {

View File

@ -1,14 +1,14 @@
package com.github.yulichang.interceptor; package com.github.yulichang.interceptor;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit;
import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.config.ConfigProperties; import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.method.MPJResultType; import com.github.yulichang.method.MPJResultType;
import com.github.yulichang.query.MPJQueryWrapper; import com.github.yulichang.query.MPJQueryWrapper;
import com.github.yulichang.toolkit.Constant; import com.github.yulichang.toolkit.*;
import com.github.yulichang.toolkit.MPJReflectionKit;
import com.github.yulichang.toolkit.MPJTableMapperHelper;
import com.github.yulichang.toolkit.TableHelper;
import com.github.yulichang.toolkit.support.FieldCache; import com.github.yulichang.toolkit.support.FieldCache;
import com.github.yulichang.wrapper.interfaces.SelectWrapper; import com.github.yulichang.wrapper.interfaces.SelectWrapper;
import com.github.yulichang.wrapper.resultmap.IResult; import com.github.yulichang.wrapper.resultmap.IResult;
@ -41,6 +41,7 @@ import java.util.concurrent.ConcurrentHashMap;
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class})) @Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class MPJInterceptor implements Interceptor { public class MPJInterceptor implements Interceptor {
private static final boolean v = VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3.1") > 0;
private static final List<ResultMapping> EMPTY_RESULT_MAPPING = new ArrayList<>(0); private static final List<ResultMapping> EMPTY_RESULT_MAPPING = new ArrayList<>(0);
@ -286,7 +287,7 @@ public class MPJInterceptor implements Interceptor {
childId.append("]"); childId.append("]");
} }
//双检 //双检
String id = childId.toString(); String id = v ? childId.toString() : childId.toString().replaceAll("\\.", "~");
if (!ms.getConfiguration().hasResultMap(id)) { if (!ms.getConfiguration().hasResultMap(id)) {
ResultMap build = new ResultMap.Builder(ms.getConfiguration(), id, mybatisLabel.getOfType(), childMapping).build(); ResultMap build = new ResultMap.Builder(ms.getConfiguration(), id, mybatisLabel.getOfType(), childMapping).build();
MPJInterceptor.addResultMap(ms, id, build); MPJInterceptor.addResultMap(ms, id, build);

View File

@ -1,7 +1,6 @@
package com.github.yulichang.method; package com.github.yulichang.method;
import com.baomidou.mybatisplus.annotation.FieldStrategy; import com.baomidou.mybatisplus.annotation.FieldStrategy;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils; import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
@ -10,9 +9,9 @@ import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils; import com.baomidou.mybatisplus.core.toolkit.sql.SqlScriptUtils;
import com.github.yulichang.adapter.AdapterHelper; import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.adapter.base.metadata.OrderFieldInfo;
import com.github.yulichang.annotation.DynamicTableName; import com.github.yulichang.annotation.DynamicTableName;
import com.github.yulichang.config.ConfigProperties; import com.github.yulichang.config.ConfigProperties;
import com.github.yulichang.toolkit.VersionUtils;
import java.io.UnsupportedEncodingException; import java.io.UnsupportedEncodingException;
import java.net.URLEncoder; import java.net.URLEncoder;
@ -72,23 +71,19 @@ public interface MPJBaseMethod extends Constants {
*/ */
default String mpjSqlOrderBy(TableInfo tableInfo) { default String mpjSqlOrderBy(TableInfo tableInfo) {
/* 不存在排序字段,直接返回空 */ /* 不存在排序字段,直接返回空 */
List<TableFieldInfo> orderByFields; List<OrderFieldInfo> orderByFields;
try { try {
if (VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3") >= 0) { orderByFields = AdapterHelper.getTableInfoAdapter().mpjGetOrderField(tableInfo);
orderByFields = tableInfo.getOrderByFields();
} else {
return StringPool.EMPTY;
}
} catch (Exception e) { } catch (Exception e) {
return StringPool.EMPTY; return StringPool.EMPTY;
} }
if (CollectionUtils.isEmpty(orderByFields)) { if (CollectionUtils.isEmpty(orderByFields)) {
return StringPool.EMPTY; return StringPool.EMPTY;
} }
orderByFields.sort(Comparator.comparingInt(TableFieldInfo::getOrderBySort)); orderByFields.sort(Comparator.comparingInt(OrderFieldInfo::getSort));
String sql = NEWLINE + " ORDER BY " + String sql = NEWLINE + " ORDER BY " +
orderByFields.stream().map(tfi -> String.format("${ew.alias}.%s %s", tfi.getColumn(), orderByFields.stream().map(tfi -> String.format("${ew.alias}.%s %s", tfi.getColumn(),
tfi.getOrderByType())).collect(joining(",")); tfi.getType())).collect(joining(","));
/* 当wrapper中传递了orderBy属性@orderBy注解失效 */ /* 当wrapper中传递了orderBy属性@orderBy注解失效 */
return SqlScriptUtils.convertIf(sql, String.format("%s == null or %s", WRAPPER, return SqlScriptUtils.convertIf(sql, String.format("%s == null or %s", WRAPPER,
WRAPPER_EXPRESSION_ORDER), true); WRAPPER_EXPRESSION_ORDER), true);

View File

@ -5,6 +5,7 @@ import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.github.yulichang.toolkit.support.*; import com.github.yulichang.toolkit.support.*;
import org.apache.ibatis.reflection.property.PropertyNamer; import org.apache.ibatis.reflection.property.PropertyNamer;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
import java.util.Map; import java.util.Map;
@ -50,10 +51,11 @@ public final class LambdaUtils {
// 2. 反射读取 // 2. 反射读取
try { try {
Method method = func.getClass().getDeclaredMethod("writeReplace"); Method method = func.getClass().getDeclaredMethod("writeReplace");
return new ReflectLambdaMeta((java.lang.invoke.SerializedLambda) ReflectionKit.setAccessible(method).invoke(func)); method.setAccessible(true);
return new ReflectLambdaMeta((SerializedLambda) method.invoke(func), func.getClass().getClassLoader());
} catch (Throwable e) { } catch (Throwable e) {
// 3. 反射失败使用序列化的方式读取 // 3. 反射失败使用序列化的方式读取
return new ShadowLambdaMeta(SerializedLambda.extract(func)); return new ShadowLambdaMeta(com.github.yulichang.toolkit.support.SerializedLambda.extract(func));
} }
} }
} }

View File

@ -20,10 +20,8 @@ import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils; import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.github.yulichang.toolkit.reflect.GenericTypeUtils; import com.github.yulichang.toolkit.reflect.GenericTypeUtils;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.security.AccessController;
import java.util.*; import java.util.*;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
import java.util.function.Function; import java.util.function.Function;
@ -186,17 +184,6 @@ public final class ReflectionKit {
return (clazz.isPrimitive() && clazz != void.class ? PRIMITIVE_TYPE_TO_WRAPPER_MAP.get(clazz) : clazz); return (clazz.isPrimitive() && clazz != void.class ? PRIMITIVE_TYPE_TO_WRAPPER_MAP.get(clazz) : clazz);
} }
/**
* 设置可访问对象的可访问权限为 true
*
* @param object 可访问的对象
* @param <T> 类型
* @return 返回设置后的对象
*/
public static <T extends AccessibleObject> T setAccessible(T object) {
return AccessController.doPrivileged(new SetAccessibleAction<>(object));
}
public static <K, V> V computeIfAbsent(Map<K, V> concurrentHashMap, K key, Function<? super K, ? extends V> mappingFunction) { public static <K, V> V computeIfAbsent(Map<K, V> concurrentHashMap, K key, Function<? super K, ? extends V> mappingFunction) {
V v = concurrentHashMap.get(key); V v = concurrentHashMap.get(key);
if (v != null) { if (v != null) {

View File

@ -15,11 +15,10 @@
*/ */
package com.github.yulichang.toolkit.support; package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException; import java.lang.invoke.MethodHandle;
import com.baomidou.mybatisplus.core.toolkit.ReflectionKit; import java.lang.invoke.MethodHandleProxies;
import java.lang.invoke.MethodHandles;
import java.lang.reflect.Field; import java.lang.reflect.Executable;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Proxy; import java.lang.reflect.Proxy;
/** /**
@ -28,35 +27,14 @@ import java.lang.reflect.Proxy;
* Create by hcl at 2021/5/17 * Create by hcl at 2021/5/17
*/ */
public class IdeaProxyLambdaMeta implements LambdaMeta { public class IdeaProxyLambdaMeta implements LambdaMeta {
private static final Field FIELD_MEMBER_NAME;
private static final Field FIELD_MEMBER_NAME_CLAZZ;
private static final Field FIELD_MEMBER_NAME_NAME;
static {
try {
Class<?> classDirectMethodHandle = Class.forName("java.lang.invoke.DirectMethodHandle");
FIELD_MEMBER_NAME = ReflectionKit.setAccessible(classDirectMethodHandle.getDeclaredField("member"));
Class<?> classMemberName = Class.forName("java.lang.invoke.MemberName");
FIELD_MEMBER_NAME_CLAZZ = ReflectionKit.setAccessible(classMemberName.getDeclaredField("clazz"));
FIELD_MEMBER_NAME_NAME = ReflectionKit.setAccessible(classMemberName.getDeclaredField("name"));
} catch (ClassNotFoundException | NoSuchFieldException e) {
throw new MybatisPlusException(e);
}
}
private final Class<?> clazz; private final Class<?> clazz;
private final String name; private final String name;
public IdeaProxyLambdaMeta(Proxy func) { public IdeaProxyLambdaMeta(Proxy func) {
InvocationHandler handler = Proxy.getInvocationHandler(func); MethodHandle dmh = MethodHandleProxies.wrapperInstanceTarget(func);
try { Executable executable = MethodHandles.reflectAs(Executable.class, dmh);
Object dmh = ReflectionKit.setAccessible(handler.getClass().getDeclaredField("val$target")).get(handler); clazz = executable.getDeclaringClass();
Object member = FIELD_MEMBER_NAME.get(dmh); name = executable.getName();
clazz = (Class<?>) FIELD_MEMBER_NAME_CLAZZ.get(member);
name = (String) FIELD_MEMBER_NAME_NAME.get(member);
} catch (IllegalAccessException | NoSuchFieldException e) {
throw new MybatisPlusException(e);
}
} }
@Override @Override

View File

@ -16,36 +16,22 @@
package com.github.yulichang.toolkit.support; package com.github.yulichang.toolkit.support;
import com.baomidou.mybatisplus.core.exceptions.MybatisPlusException;
import com.baomidou.mybatisplus.core.toolkit.StringPool; import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.github.yulichang.toolkit.ClassUtils; import com.github.yulichang.toolkit.ClassUtils;
import com.github.yulichang.toolkit.ReflectionKit;
import java.lang.invoke.SerializedLambda; import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
/** /**
* Created by hcl at 2021/5/14 * Created by hcl at 2021/5/14
*/ */
public class ReflectLambdaMeta implements LambdaMeta { public class ReflectLambdaMeta implements LambdaMeta {
private static final Field FIELD_CAPTURING_CLASS;
static {
Field fieldCapturingClass;
try {
Class<SerializedLambda> aClass = SerializedLambda.class;
fieldCapturingClass = ReflectionKit.setAccessible(aClass.getDeclaredField("capturingClass"));
} catch (Throwable e) {
// 解决高版本 jdk 的问题 gitee: https://gitee.com/baomidou/mybatis-plus/issues/I4A7I5
fieldCapturingClass = null;
}
FIELD_CAPTURING_CLASS = fieldCapturingClass;
}
private final SerializedLambda lambda; private final SerializedLambda lambda;
public ReflectLambdaMeta(SerializedLambda lambda) { private final ClassLoader classLoader;
public ReflectLambdaMeta(SerializedLambda lambda, ClassLoader classLoader) {
this.lambda = lambda; this.lambda = lambda;
this.classLoader = classLoader;
} }
@Override @Override
@ -57,19 +43,7 @@ public class ReflectLambdaMeta implements LambdaMeta {
public Class<?> getInstantiatedClass() { public Class<?> getInstantiatedClass() {
String instantiatedMethodType = lambda.getInstantiatedMethodType(); String instantiatedMethodType = lambda.getInstantiatedMethodType();
String instantiatedType = instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(StringPool.SEMICOLON)).replace(StringPool.SLASH, StringPool.DOT); String instantiatedType = instantiatedMethodType.substring(2, instantiatedMethodType.indexOf(StringPool.SEMICOLON)).replace(StringPool.SLASH, StringPool.DOT);
return ClassUtils.toClassConfident(instantiatedType, getCapturingClassClassLoader()); return ClassUtils.toClassConfident(instantiatedType, this.classLoader);
}
private ClassLoader getCapturingClassClassLoader() {
// 如果反射失败使用默认的 classloader
if (FIELD_CAPTURING_CLASS == null) {
return null;
}
try {
return ((Class<?>) FIELD_CAPTURING_CLASS.get(lambda)).getClassLoader();
} catch (IllegalAccessException e) {
throw new MybatisPlusException(e);
}
} }
} }

View File

@ -51,7 +51,7 @@
<dependency> <dependency>
<groupId>com.baomidou</groupId> <groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId> <artifactId>mybatis-plus-extension</artifactId>
<version>3.5.3.2</version> <version>3.5.4</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>

View File

@ -4,6 +4,7 @@ import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo; import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfo; import com.baomidou.mybatisplus.core.metadata.TableInfo;
import com.baomidou.mybatisplus.core.toolkit.*; import com.baomidou.mybatisplus.core.toolkit.*;
import com.github.yulichang.adapter.AdapterHelper;
import com.github.yulichang.annotation.EntityMapping; import com.github.yulichang.annotation.EntityMapping;
import com.github.yulichang.annotation.FieldMapping; import com.github.yulichang.annotation.FieldMapping;
import com.github.yulichang.toolkit.SpringContentUtils; import com.github.yulichang.toolkit.SpringContentUtils;
@ -156,7 +157,7 @@ public class MPJTableFieldInfo {
Assert.notNull(info, "未注册的实体类 <%s>", this.joinClass.getSimpleName()); Assert.notNull(info, "未注册的实体类 <%s>", this.joinClass.getSimpleName());
//根据属性名查询 //根据属性名查询
Field field = info.getFieldList().stream().filter(i -> i.getProperty().equals(bindName)) Field field = info.getFieldList().stream().filter(i -> i.getProperty().equals(bindName))
.findFirst().map(TableFieldInfo::getField).orElse(null); .findFirst().map(f -> getField(this.joinClass, f)).orElse(null);
if (field == null && bindName.equals(info.getKeyProperty())) { if (field == null && bindName.equals(info.getKeyProperty())) {
field = ReflectionKit.getFieldList(joinClass).stream().filter(f -> field = ReflectionKit.getFieldList(joinClass).stream().filter(f ->
f.getName().equals(info.getKeyProperty())).findFirst().orElse(null); f.getName().equals(info.getKeyProperty())).findFirst().orElse(null);
@ -165,7 +166,7 @@ public class MPJTableFieldInfo {
//根据字段查询 //根据字段查询
field = info.getFieldList().stream() field = info.getFieldList().stream()
.filter(i -> i.getColumn().equals(bindName)) .filter(i -> i.getColumn().equals(bindName))
.map(TableFieldInfo::getField).findFirst().orElse(null); .map(f -> getField(this.joinClass, f)).findFirst().orElse(null);
if (field == null && bindName.equals(info.getKeyColumn())) { if (field == null && bindName.equals(info.getKeyColumn())) {
field = ReflectionKit.getFieldList(joinClass).stream().filter(f -> field = ReflectionKit.getFieldList(joinClass).stream().filter(f ->
f.getName().equals(info.getKeyProperty())).findFirst().orElse(null); f.getName().equals(info.getKeyProperty())).findFirst().orElse(null);
@ -175,6 +176,7 @@ public class MPJTableFieldInfo {
} }
} }
this.bindField = field; this.bindField = field;
this.bindField.setAccessible(true);
} }
private void initJoinField(String joinField) { private void initJoinField(String joinField) {
@ -188,16 +190,16 @@ public class MPJTableFieldInfo {
TableInfo joinTableInfo = getTableInfo(this.joinClass); TableInfo joinTableInfo = getTableInfo(this.joinClass);
TableFieldInfo joinFieldInfo = joinTableInfo.getFieldList().stream().filter(f -> TableFieldInfo joinFieldInfo = joinTableInfo.getFieldList().stream().filter(f ->
f.getField().getName().equals(this.joinProperty)).findFirst().orElse(null); f.getProperty().equals(this.joinProperty)).findFirst().orElse(null);
if (joinFieldInfo == null) { if (joinFieldInfo == null) {
if (joinTableInfo.havePK() && this.joinProperty.equals(joinTableInfo.getKeyProperty())) { if (AdapterHelper.getTableInfoAdapter().mpjHasPK(joinTableInfo) && this.joinProperty.equals(joinTableInfo.getKeyProperty())) {
this.joinColumn = joinTableInfo.getKeyColumn(); this.joinColumn = joinTableInfo.getKeyColumn();
this.joinField = ReflectionKit.getFieldList(this.joinClass).stream().filter(i -> this.joinField = ReflectionKit.getFieldList(this.joinClass).stream().filter(i ->
i.getName().equals(joinTableInfo.getKeyProperty())).findFirst().orElse(null); i.getName().equals(joinTableInfo.getKeyProperty())).findFirst().orElse(null);
} }
} else { } else {
this.joinColumn = joinFieldInfo.getColumn(); this.joinColumn = joinFieldInfo.getColumn();
this.joinField = joinFieldInfo.getField(); this.joinField = getField(this.joinClass, joinFieldInfo);
} }
Assert.notNull(this.joinField, "注解属性thisField不存在 %s , %s", this.joinClass.getName(), Assert.notNull(this.joinField, "注解属性thisField不存在 %s , %s", this.joinClass.getName(),
StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty); StringUtils.isBlank(this.joinProperty) ? "主键" : this.joinProperty);
@ -216,7 +218,7 @@ public class MPJTableFieldInfo {
} }
TableInfo tableInfo = getTableInfo(this.entityType); TableInfo tableInfo = getTableInfo(this.entityType);
if (tableInfo.havePK() && this.thisProperty.equals(tableInfo.getKeyProperty())) { if (AdapterHelper.getTableInfoAdapter().mpjHasPK(tableInfo) && this.thisProperty.equals(tableInfo.getKeyProperty())) {
this.thisField = ReflectionKit.getFieldList(ClassUtils.getUserClass(entityType)).stream().filter(f -> this.thisField = ReflectionKit.getFieldList(ClassUtils.getUserClass(entityType)).stream().filter(f ->
f.getName().equals(tableInfo.getKeyProperty())).findFirst().orElse(null); f.getName().equals(tableInfo.getKeyProperty())).findFirst().orElse(null);
Assert.notNull(this.thisField, "注解属性thisField不存在 %s , %s", entityType.getName(), Assert.notNull(this.thisField, "注解属性thisField不存在 %s , %s", entityType.getName(),
@ -224,10 +226,10 @@ public class MPJTableFieldInfo {
this.thisColumn = tableInfo.getKeyColumn(); this.thisColumn = tableInfo.getKeyColumn();
} else { } else {
TableFieldInfo fieldInfo = tableInfo.getFieldList().stream().filter(f -> TableFieldInfo fieldInfo = tableInfo.getFieldList().stream().filter(f ->
f.getField().getName().equals(this.thisProperty)).findFirst().orElse(null); f.getProperty().equals(this.thisProperty)).findFirst().orElse(null);
Assert.notNull(fieldInfo, "注解属性thisField不存在 %s , %s", entityType.getName(), Assert.notNull(fieldInfo, "注解属性thisField不存在 %s , %s", entityType.getName(),
StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty); StringUtils.isBlank(this.thisProperty) ? "主键" : this.thisProperty);
this.thisField = fieldInfo.getField(); this.thisField = getField(this.entityType, fieldInfo);
this.thisColumn = fieldInfo.getColumn(); this.thisColumn = fieldInfo.getColumn();
} }
this.thisField.setAccessible(true); this.thisField.setAccessible(true);
@ -311,6 +313,11 @@ public class MPJTableFieldInfo {
return tableInfo; return tableInfo;
} }
private Field getField(Class<?> table, TableFieldInfo tableFieldInfo) {
return AdapterHelper.getTableInfoAdapter().mpjGetField(tableFieldInfo, () ->
ReflectionKit.getFieldMap(table).get(tableFieldInfo.getProperty()));
}
public void fieldSet(Object o, Object val) { public void fieldSet(Object o, Object val) {
try { try {
this.field.set(o, val); this.field.set(o, val);
@ -368,7 +375,7 @@ public class MPJTableFieldInfo {
} else { } else {
if (data.size() > 1 && fieldInfo.isThrowExp()) { if (data.size() > 1 && fieldInfo.isThrowExp()) {
throw ExceptionUtils.mpe("Expected one result (or null) to be returned by select, but found: " + throw ExceptionUtils.mpe("Expected one result (or null) to be returned by select, but found: " +
data.size() + " , " + fieldInfo.getField().getName()); data.size() + " , " + fieldInfo.getProperty());
} else { } else {
fieldInfo.fieldSet(i, data.stream().findFirst().orElse(null)); fieldInfo.fieldSet(i, data.stream().findFirst().orElse(null));
} }

View File

@ -1,9 +1,11 @@
package com.github.yulichang.test.join; package com.github.yulichang.test.join;
import com.baomidou.mybatisplus.core.MybatisPlusVersion;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper; import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage; import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils; import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page; import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.github.yulichang.adapter.base.tookit.VersionUtils;
import com.github.yulichang.test.join.dto.AddressDTO; import com.github.yulichang.test.join.dto.AddressDTO;
import com.github.yulichang.test.join.dto.UserDTO; import com.github.yulichang.test.join.dto.UserDTO;
import com.github.yulichang.test.join.entity.*; import com.github.yulichang.test.join.entity.*;
@ -959,13 +961,23 @@ class LambdaWrapperTest {
*/ */
@Test @Test
void joinOrder() { void joinOrder() {
if (VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3") >= 0) {
ThreadLocalUtils.set("SELECT id,user_id,name FROM order_t t ORDER BY t.name DESC", ThreadLocalUtils.set("SELECT id,user_id,name FROM order_t t ORDER BY t.name DESC",
"SELECT id,user_id,name FROM order_t t ORDER BY t.name desc"); "SELECT id,user_id,name FROM order_t t ORDER BY t.name desc");
} else {
ThreadLocalUtils.set("SELECT id,user_id,name FROM order_t t",
"SELECT id,user_id,name FROM order_t t");
}
MPJLambdaWrapper<OrderDO> wrapper = JoinWrappers.lambda(OrderDO.class); MPJLambdaWrapper<OrderDO> wrapper = JoinWrappers.lambda(OrderDO.class);
List<OrderDO> list = wrapper.list(); List<OrderDO> list = wrapper.list();
if (VersionUtils.compare(MybatisPlusVersion.getVersion(), "3.4.3") >= 0) {
ThreadLocalUtils.set("SELECT t.id,t.user_id,t.name,t1.`name` AS userName FROM order_t t LEFT JOIN `user` t1 ON (t1.id = t.user_id) WHERE t1.del=false ORDER BY t.name DESC", ThreadLocalUtils.set("SELECT t.id,t.user_id,t.name,t1.`name` AS userName FROM order_t t LEFT JOIN `user` t1 ON (t1.id = t.user_id) WHERE t1.del=false ORDER BY t.name DESC",
"SELECT t.id,t.user_id,t.name,t1.`name` AS userName FROM order_t t LEFT JOIN `user` t1 ON (t1.id = t.user_id) WHERE t1.del=false ORDER BY t.name desc"); "SELECT t.id,t.user_id,t.name,t1.`name` AS userName FROM order_t t LEFT JOIN `user` t1 ON (t1.id = t.user_id) WHERE t1.del=false ORDER BY t.name desc");
} else {
ThreadLocalUtils.set("SELECT t.id,t.user_id,t.name,t1.`name` AS userName FROM order_t t LEFT JOIN `user` t1 ON (t1.id = t.user_id) WHERE t1.del=false",
"SELECT t.id,t.user_id,t.name,t1.`name` AS userName FROM order_t t LEFT JOIN `user` t1 ON (t1.id = t.user_id) WHERE t1.del=false");
}
MPJLambdaWrapper<OrderDO> w = JoinWrappers.lambda(OrderDO.class) MPJLambdaWrapper<OrderDO> w = JoinWrappers.lambda(OrderDO.class)
.selectAll(OrderDO.class) .selectAll(OrderDO.class)
.selectAs(UserDO::getName, OrderDO::getUserName) .selectAs(UserDO::getName, OrderDO::getUserName)