一、mybatis-plus 中使用示例暂时

我们在开发中经常使用 mybatis-plus 中使用Lambda :: get… 获取对象属性名,那么他是如何实现的呢?
在这里插入图片描述

二、创建可以使用类型功能的工具类

1、创建 SFunction 注解

传递: 使用 User::getUaerame 来传递对象属性名 ,
接收: 使用 SFunction<T> fn 接收对象属性信息

/**
 * @classname: SFunction
 * @create: 2019-09-25 12:57
 **/
@FunctionalInterface
public interface SFunction<T> extends Serializable {
    Object get(T source);
}
2、创建 LambdaTypeInfo 类解析 Function 获取属性名
package com.ws.ldy.common.function;


import com.ws.ldy.admin.model.entity.UserAdmin;

import java.io.Serializable;
import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * TODO  通过 Lambda 获取对象属性名
 * 使用方法: LambdaTypeInfo.convertToFieldName(Test::getName)
 *
 * @author ws
 * @mail 1720696548@qq.com
 * @date 2020/4/12 0012 14:31
 */
class LambdaTypeInfo {

    private static Map<Class, SerializedLambda> CLASS_LAMBDA_CACHE = new ConcurrentHashMap<>();

    /***
     * 转换方法引用为属性名
     * @param fn
     * @return
     */
    static <T> String convertToFieldName(SFunction<T> fn) {
        SerializedLambda lambda = getSerializedLambda(fn);
        // 获取方法名
        String methodName = lambda.getImplMethodName();
        String prefix = null;
        if (methodName.startsWith("get")) {
            prefix = "get";
        } else if (methodName.startsWith("is")) {
            prefix = "is";
        }
        if (prefix == null) {
            System.out.println("无效的getter方法: " + methodName);
        }
        // 截取get/is之后的字符串并转换首字母为小写
        return toLowerCaseFirstOne(methodName.replace(prefix, ""));
    }

    /**
     * 首字母转小写
     *
     * @param s
     * @return
     */
    static String toLowerCaseFirstOne(String s) {
        if (Character.isLowerCase(s.charAt(0))) {
            return s;
        } else {
            return Character.toLowerCase(s.charAt(0)) + s.substring(1);
        }
    }

    /**
     * 关键在于这个方法
     */
    static SerializedLambda getSerializedLambda(Serializable fn) {
        SerializedLambda lambda = CLASS_LAMBDA_CACHE.get(fn.getClass());
        // 先检查缓存中是否已存在
        if (lambda == null) {
            try {
                // 提取SerializedLambda并缓存
                Method method = fn.getClass().getDeclaredMethod("writeReplace");
                method.setAccessible(Boolean.TRUE);
                lambda = (SerializedLambda) method.invoke(fn);
                CLASS_LAMBDA_CACHE.put(fn.getClass(), lambda);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return lambda;
    }


    /**
     * TODO 测试通过 Lambda 获取对象属性名
     *
     * @param args
     * @return void
     * @author ws
     * @mail 1720696548@qq.com
     * @date 2020/4/24 0024 9:47
     */
    public static void main(String[] args) {
        System.out.println(LambdaTypeInfo.convertToFieldName(UserAdmin::getAccount));
    }

}

3、测试代码
    /**
     * TODO 测试通过 Lambda 获取对象属性名
     *
     * @param args
     * @return void
     * @author ws
     * @mail 1720696548@qq.com
     * @date 2020/4/24 0024 9:47
     */
    public static void main(String[] args) {
        System.out.println(LambdaTypeInfo.convertToFieldName(UserAdmin::getAccount));
    }

在这里插入图片描述
实际获取到的内容等于实体类的属性名,在DDL 框架中使用此方式可以大大的避免每次动态拼接sql写字段名时的书写错误的情况发生
在这里插入图片描述

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐