Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[功能改进]: groovy的lambda构造器支持 #6482

Open
3 tasks done
qiuhuanhen opened this issue Sep 12, 2024 · 0 comments
Open
3 tasks done

[功能改进]: groovy的lambda构造器支持 #6482

qiuhuanhen opened this issue Sep 12, 2024 · 0 comments

Comments

@qiuhuanhen
Copy link

qiuhuanhen commented Sep 12, 2024

确认

  • 我的版本是最新版本, 我的版本号与 version 相同, 并且项目里无依赖冲突
  • 我已经在 issue 中搜索过, 确认问题没有被提出过
  • 我已经修改标题, 将标题中的 描述 替换为遇到的问题

功能改进

在使用groovy脚本时,如果直接使用LambdaQueryWrapper :: 会报错,
目前看extension包 有kotlin的AbstractKtWrapper , 里面定义了columnsToString方法 ,潜潜推测一下 应该是和groovy类似情况,无法使用java标准的lambda处理方式。

产生原因:
源码 LambdaQueryWrapper中 最终调用LambdaUtils的extract方法转换的

`   public static <T> LambdaMeta extract(SFunction<T, ?> func) {
    // groovy脚本也是走代理
    if (func instanceof Proxy) {
        //  抛出异常 throw newIllegalArgumentException("not a wrapper instance");
        return new IdeaProxyLambdaMeta((Proxy) func);
    } else {
        try {
            Method method = func.getClass().getDeclaredMethod("writeReplace");
            method.setAccessible(true);
            return new ReflectLambdaMeta((SerializedLambda) method.invoke(func), func.getClass().getClassLoader());
        } catch (Throwable var2) {
            return new ShadowLambdaMeta(com.baomidou.mybatisplus.core.toolkit.support.SerializedLambda.extract(func));
        }
    }
}`

能否建一个groovy的相关wrapper ,处理 :: to String ,
目前临时解决方案是用的如下代码 在QueryWrapper普通构造器r中 手动将:: 转成String的

new QueryWrapper().eq(function2StrInGroovy(Entity::getField),value)

测试通过 Script script = GroovyShell.parse(text); script .run() 场景

`   public static <T> String function2StrInGroovy(Function<T, ?> function) {
    // 获取动态代理处理器  (groovy脚本中 function被groovy包相关类代理 )
    InvocationHandler handler = Proxy.getInvocationHandler(function);

    // 从本类、父类中查找方法
    Method[] methods = handler.getClass().getMethods();
    for (Method method : methods) {
        // 在handler的delegate里面
        if (Objects.equals("getDelegate",method.getName())) {
            // Groovy 使用的是 Closure  而非Java的标准Lambda
            MethodClosure delegate = null;
            try {
                delegate = (MethodClosure) method.invoke(handler);
            } catch (IllegalAccessException | InvocationTargetException e) {
                throw new RuntimeException(e);
            }
            // 拿到get方法 并截取转字符串 
            String methodName = delegate.getMethod();
           // 这里也可以直接调用mybatis的PropertyNamer#methodToProperty方法
            String temp = methodName.substring(3);
            temp = temp.replaceFirst(temp.substring(0, 1), temp.substring(0, 1).toLowerCase());
            return temp;
        }
    }
    throw new RuntimeException("can't found method");
}`

参考资料

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant