V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
anzu
V2EX  ›  Java

MyBatis 一个比较奇怪的参数绑定问题

  •  
  •   anzu · 2021-05-11 15:51:34 +08:00 · 2321 次点击
    这是一个创建于 1319 天前的主题,其中的信息可能已经有所发展或是发生改变。

    众所周知如果 Mapper 需要多个参数时,需要在每个参数前加上 @ Param 注解,如:

    User findByUserIdAndName(@Param("userId") Integer userId, @Param("name") String name);
    

    但是我不加也可以,于是我没加,正常运行。 现在重构项目,拆分成父子项目,结果全部报错:org.apache.ibatis.binding.BindingException: Parameter 'xxx' not found. 网上都说是没加 @ Param 的原因,的确现在加上就不报错,但是为什么我之前没加也可以呢?

    第 1 条附言  ·  2021-05-11 16:58:40 +08:00

    我懂了! 根据这里的回答 https://stackoverflow.com/a/49316086

    To allow the input to be mapped to the operation method’s parameters, code implementing an endpoint should be compiled with -parameters. This will happen automatically if you are using Spring Boot’s Gradle plugin or if you are using Maven and spring-boot-starter-parent.
    

    查看 spring-boot-starter-parent pom 文件,可以看到maven-compiler-plugin设置了 -parameters

    所以 spring 项目编译时会自动加上 -parameters

    但是,现在我重构了项目,删除了 spring-boot-starter-parent,把spring-boot-dependencies加入父项目的dependencyManagement,也就是

        <dependency>
    	<groupId>org.springframework.boot</groupId>
    	<artifactId>spring-boot-dependencies</artifactId>
    	<type>pom</type>
    	<version>2.4.5</version>
    	<scope>import</scope>
        </dependency>
    

    但是这家伙没有设置 -parameters,于是查询报错

    6 条回复    2021-05-12 12:13:16 +08:00
    qinxi
        1
    qinxi  
       2021-05-11 15:56:23 +08:00   ❤️ 1
    猜测: 之前编译保留了参数名, 拆分后编译参数名被抹去了
    msaionyc
        2
    msaionyc  
       2021-05-11 16:29:57 +08:00   ❤️ 1
    https://www.codenong.com/cs110818507/
    感觉是这个原因,之前也有遇到过,但没有去深入了解
    mitsuizzz
        3
    mitsuizzz  
       2021-05-11 16:32:40 +08:00   ❤️ 1
    之前遇到过这个问题,网上查了很久,千奇百怪的。
    最后发现是编译设定有关,本地 ide 默认给你加了个-parameters 参数导致编译保留了参数名不会报错。
    详情参考:
    https://www.concretepage.com/java/jdk-8/java-8-reflection-access-to-parameter-names-of-method-and-constructor-with-maven-gradle-and-eclipse-using-parameters-compiler-argument#compiler-argument
    shoushi
        4
    shoushi  
       2021-05-11 19:16:03 +08:00
    是我之前遇到的问题了!多谢
    yhpz
        5
    yhpz  
       2021-05-11 23:57:32 +08:00
    可以看下 MyBatis 源码中 ParamNameResolver 这个类:
    for (Annotation annotation : paramAnnotations[paramIndex]) {
    // 方法参数中,是否有 Param 注解
    if (annotation instanceof Param) {
    hasParamAnnotation = true;
    // 获取参数名称
    name = ((Param) annotation).value();
    break;
    }
    }
    if (name == null) {
    // 未指定 @Param 注解,这判断是否使用实际的参数名称,参考 useActualParamName 属性的作用,IDEA 需要加 -parameters 参数
    if (config.isUseActualParamName()) {
    // 获取参数名
    name = getActualParamName(method, paramIndex);
    }
    if (name == null) {
    name = String.valueOf(map.size());
    }
    }
    siweipancc
        6
    siweipancc  
       2021-05-12 12:13:16 +08:00 via iPhone
    啊这……spring cache 一章有讲,还加红了
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2670 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 25ms · UTC 05:32 · PVG 13:32 · LAX 21:32 · JFK 00:32
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.