在使用mybatis-plus的lambdaQueryWrapper后,发现使用lambda匿名表达式的方式进行方法名的输入优雅且更换方法名也不用去修改硬编码的字段属性名,那么我们在开发中如何使用呢?
工具类
package com.inovance.eurekaclient.easyMongo.utils;
import com.inovance.eurekaclient.easyMongo.sdk.base.SFunction;
import javax.ws.rs.GET;
import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ConcurrentHashMap;
/**
* @Description
* @Author daWang ju
* @Time 2023/08/03/11:15
* @Version 1.0
*/
public class ConvertUtil {
public ConvertUtil() {
}
public static final String GET = "get";
public static final String IS = "is";
/**
* 缓存方法应用对应的属性名称
*/
private static final Map<Class<?>, String> CLASS_FIELD_META_MAP = new ConcurrentHashMap<>();
public static <T> String convertToFieldName(SFunction<T, ?> fn) {
String cacheData = CLASS_FIELD_META_MAP.get(fn.getClass());
if (Objects.nonNull(cacheData)) {
return cacheData;
}
SerializedLambda lambda = getSerializedLambda(fn);
String methodName = lambda.getImplMethodName();
if (methodName.startsWith(GET)) {
methodName = methodName.substring(3);
} else if (methodName.startsWith(IS)) {
methodName = methodName.substring(2);
} else {
throw new IllegalArgumentException("无效的getter方法" + methodName);
}
try {
String fieldMeta = StringUtils.firstToLowerCase(methodName);
CLASS_FIELD_META_MAP.put(fn.getClass(), fieldMeta);
return fieldMeta;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
/**
* 获取一个实现了序列化的lambda函数
*
* @param fn 目标函数
* @return 实现了序列化的lambda函数
*/
public static SerializedLambda getSerializedLambda(Serializable fn) {
SerializedLambda lambda;
try {
// 提取SerializedLambda并缓存
Method method = fn.getClass().getDeclaredMethod("writeReplace");
method.setAccessible(Boolean.TRUE);
lambda = (SerializedLambda) method.invoke(fn);
} catch (NoSuchMethodException | InvocationTargetException | IllegalAccessException e) {
throw new RuntimeException(e);
}
return lambda;
}
}