确认

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

功能改进

在使用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

Comment From: hgdhfq

4034 参考这里