LambdaQueryWrapper模拟实现

Posted £漫步 云端彡

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LambdaQueryWrapper模拟实现相关的知识,希望对你有一定的参考价值。

一、LambdaQueryWrapper?

LambdaQueryWrapper是Mybatis-Plus插件的对象,实现了使用lambda形式构造查询接口。
最初接触这个的时候,第一感觉就是,太方便了,因避免是用大量的字符串,对日后的维护有着很重要的作用。

二、类名::GET方法

在LambdaQueryWrapper构造语句的方法中使用了大量的这种方式作为查询数据库的字段名。这种方式还可指定具体的类。

类名::GET方法,这是lambda的调用Get方法,简化操作的,例:

List<String> list = new ArrayLiast();
list.add("Hello");
//化简前
list.forEach(item -> System.out.println(item));
//化简后
list.forEach(System.out::println);

具体使用可自行百度,:: 实现是其实使用的是Function<T, R>接口,该接口声明@FunctionalInterface,即这是函数式接口。


二、如何结合使用?

LambdaQueryWrapper 查询需要的是字段名,而::得到的是执行get方法。那么mybatis-plus到底是怎么将get方法转换为字段的呢。并不是执行呢?
IDEA调试方法可知如下:

类名::GET方法实际类型是Function<T,R>,而mybatis-plus使用新的接口SFunction<T,R>将Function序列化后,该Function接口会在运行时添加writeReplace方法,可以查看当前执行方法的类名、方法名等信息。然后通过方法名解析出字段名。

三、示例代码

@FunctionalInterface
public interface SFunction<T,R> extends Function<T,R>, Serializable 

public class User 
    private String username;
    private String password;
	// get、set略

public class Builder<T> 
    private T target;

    public Builder(Class<T> tClass) 
        try 
            target = tClass.newInstance();
         catch (InstantiationException e) 
            e.printStackTrace();
         catch (IllegalAccessException e) 
            e.printStackTrace();
        
    

    public static <T> Builder<T> builder(Class<T> tClass) 
        return new Builder(tClass);
    
    public <T,R> String getFunName(SFunction<T, R> sFunction) 
        try 
            // 直接调用writeReplace
            Method methods = sFunction.getClass().getDeclaredMethod("writeReplace");
            methods.setAccessible(true);
            //反射调用
            Object sl = methods.invoke(sFunction);
            SerializedLambda serializedLambda = (SerializedLambda) sl;
            // 获取类
            String implClass = serializedLambda.getImplClass();
            Class<?> aClass = Class.forName(implClass.replace("/", "."));
            // 获取方法名
            String methodName = serializedLambda.getImplMethodName();
            return methodName;
         catch (NoSuchMethodException e) 
            e.printStackTrace();
         catch (IllegalAccessException e) 
            e.printStackTrace();
         catch (InvocationTargetException e) 
            e.printStackTrace();
         catch (ClassNotFoundException e) 
            e.printStackTrace();
        
        // 获取值
        return null;
    

public class Main 
    public static void main(String[] args) 
        Builder<User> builder = Builder.builder(User.class);
        String name = builder.getFunName(User::getUsername);
        System.out.println(name);
    

运行结果:

getUsername

总结

通过上面的示例,轻而易举可获取到方法的名或字段名或者其他信息。上面的代码在业务需求方面没有什么用处。但是在构造条件情况下,结合设计模式,有很醒目的作用,能够给编程带来便利。

以上是关于LambdaQueryWrapper模拟实现的主要内容,如果未能解决你的问题,请参考以下文章

LambdaQueryWrapper模拟实现

MyBatis-Plus 之LambdaQueryWrapper 实现And/Or 查询

LambdaQueryWrapper&QueryWrapper增删改CURD使用教程案例

全网详解MyBatis-Plus LambdaQueryWrapper的使用说明以及LambdaQueryWrapper和QueryWapper的区别

【超线程用处大吗】;‘;

Mybatis Plus中的lambdaQueryWrapper条件构造图介绍