Mybatis Plus 如何通過lambda獲取屬性名,源碼解析

最近項目中使用mybatisplus 作爲項目的orm,效率比mybatis提升了不少,用起來相當方便,其中通過lambda表達式取得字段名,特別方便

        LambdaQueryWrapper<SpClips> where = new LambdaQueryWrapper<>();
        where.in(SpClips::getClipId, ids);

這是怎麼實現的呢,帶着好奇心我們來分析一下這塊的源碼。
首先我們看下 AbstractLambdaWrapper 抽象類

    protected String columnToString(SFunction<T, ?> column, boolean onlyColumn) {
        return getColumn(LambdaUtils.resolve(column), onlyColumn);
    }

columnToString 函數將lambda表達式轉換成字段名,
我們再看下 LambdaUtils.resolve(column) 這行代碼處理的邏輯

    /**
     * 解析 lambda 表達式, 該方法只是調用了 {@link SerializedLambda#resolve(SFunction)} 中的方法,在此基礎上加了緩存。
     * 該緩存可能會在任意不定的時間被清除
     *
     * @param func 需要解析的 lambda 對象
     * @param <T>  類型,被調用的 Function 對象的目標類型
     * @return 返回解析後的結果
     * @see SerializedLambda#resolve(SFunction)
     */
    public static <T> SerializedLambda resolve(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;
            });
    }

該段代碼將lambda表達式轉換成 SerializedLambda 對象,我們在來看看SerializedLambda 有哪些信息

    private Class<?> capturingClass;
    private String functionalInterfaceClass;
    private String functionalInterfaceMethodName;
    private String functionalInterfaceMethodSignature;
    private String implClass;
    private String implMethodName;
    private String implMethodSignature;
    private int implMethodKind;
    private String instantiatedMethodType;
    private Object[] capturedArgs;

這裏面有方法名信息,到目前爲止,實現思路就比較清楚了,

在這裏插入圖片描述
初始化類:TableInfoHelper
核心類:LambdaUtils 、SerializedLambda

大家有興趣可以深入看下這幾個類的代碼

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章