Mybatis-Plus中有一个非常牛逼的技能,只需要传入get方法引用,内部就可以获取得到属性名,这个功能很有用啊。
实现方式如下:
Step1: 先创建一个接口类:SFunction
```java
import java.io.Serializable;
@FunctionalInterface
public interface SFunction extends Serializable {
R apply(T t);
}
```
Step2:
```java
import java.io.*;
import java.lang.ref.WeakReference;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
@SuppressWarnings("unused")
public class SerializedLambda implements Serializable {
private static final long serialVersionUID = 8025925345765570181L;
private String implMethodName;
//获取索性名的方法
public static String getColumnName(SFunction column) {
return resolveFieldName(resolveFunc(column).getImplMethodName());
}
/**
* 通过反序列化转换 lambda 表达式,该方法只能序列化 lambda 表达式,不能序列化接口实现或者正常非 lambda 写法的对象
*
* @param lambda lambda对象
* @return 返回解析后的 SerializedLambda
*/
public static SerializedLambda resolve(SFunction lambda) {
if (!lambda.getClass().isSynthetic()) {
throw new RuntimeException("该方法仅能传入 lambda 表达式产生的合成类");
}
try (ObjectInputStream objIn = new ObjectInputStream(new ByteArrayInputStream(serialize(lambda))) {
@Override
protected Class> resolveClass(ObjectStreamClass objectStreamClass) throws IOException, ClassNotFoundException {
Class> clazz = super.resolveClass(objectStreamClass);
return clazz == java.lang.invoke.SerializedLambda.class ? SerializedLambda.class : clazz;
}
}) {
return (SerializedLambda) objIn.readObject();
} catch (ClassNotFoundException | IOException e) {
throw new RuntimeException("This is impossible to happen", e);
}
}
/**
* Serialize the given object to a byte array.
* @param object the object to serialize
* @return an array of bytes representing the object in a portable fashion
*/
public static byte[] serialize(Object object) {
if (object == null) {
return null;
}
ByteArrayOutputStream baos = new ByteArrayOutputStream(1024);
try {
ObjectOutputStream oos = new ObjectOutputStream(baos);
oos.writeObject(object);
oos.flush();
} catch (IOException ex) {
throw new IllegalArgumentException("Failed to serialize object of type: " + object.getClass(), ex);
}
return baos.toByteArray();
}
/**
* SerializedLambda 反序列化缓存
*/
private static final Map> FUNC_CACHE = new ConcurrentHashMap<>();
/**
*
* 解析 lambda 表达式
*
*
* @param func 需要解析的 lambda 对象
* @param 类型,被调用的 Function 对象的目标类型
* @return 返回解析后的结果
*/
public static SerializedLambda resolveFunc(SFunction func) {
Class clazz = func.getClass();
return Optional.ofNullable(FUNC_CACHE.get(clazz))
.map(WeakReference::get)
.orElseGet(() -> {
SerializedLambda lambda = SerializedLambda.resolve(func);
FUNC_CACHE.put(clazz, new WeakReference<>(lambda));
return lambda;
});
}
/**
*
* 解析 getMethodName -> propertyName
*
*
* @param getMethodName 需要解析的
* @return 返回解析后的字段名称
*/
public static String resolveFieldName(String getMethodName) {
if (getMethodName.startsWith("get")) {
getMethodName = getMethodName.substring(3);
} else if (getMethodName.startsWith("is")) {
getMethodName = getMethodName.substring(2);
}
// 小写第一个字母
return firstToLowerCase(getMethodName);
}
/**
*
* 首字母转换小写
*
*
* @param param 需要转换的字符串
* @return 转换好的字符串
*/
public static String firstToLowerCase(String param) {
if (StringUtils.isEmptyOrNull(param)) {
return "";
}
return param.substring(0, 1).toLowerCase() + param.substring(1);
}
/**
* 获取实现者的方法名称
*
* @return 方法名称
*/
public String getImplMethodName() {
return implMethodName;
}
}
```
Step3: 调用
SerializedLambda.getCollumnName(JavaBean::getXXXX)