Mybatis-Plus中有一个非常牛逼的技能,只需要传入get方法引用,内部就可以获取得到属性名,这个功能很有用啊。
实现方式如下:
Step1: 先创建一个接口类:SFunction
```java
import java.io.Serializable; @FunctionalInterface public interface SFunction<T, R> 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 <T> String getColumnName(SFunction<T, ?> 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<Class, WeakReference<SerializedLambda>> FUNC_CACHE = new ConcurrentHashMap<>(); /** * <p> * 解析 lambda 表达式 * </p> * * @param func 需要解析的 lambda 对象 * @param <T> 类型,被调用的 Function 对象的目标类型 * @return 返回解析后的结果 */ public static <T> SerializedLambda resolveFunc(SFunction<T, ?> 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; }); } /** * <p> * 解析 getMethodName -> propertyName * </p> * * @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); } /** * <p> * 首字母转换小写 * </p> * * @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)