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

大家有兴趣可以深入看下这几个类的代码

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