MyBatis解惑(持续更新…)

108 阅读2分钟

映射方法的参数,是否需要添加@Param注解

  1. @Param注解的作用
  • 使用@Param注解,可以自定义参数名称,MyBatis通过自定义名称(如下方代码中的aid,aname)匹配参数。
public User getUser(@Param("aid") Long id, @Param("aname") String name);
  • 不使用@Param注解,MyBatis默认使用映射方法参数名(如下方代码中的id,name)匹配参数。
public User getUser(Long id, String name);
  1. 为什么有时候不加@Param会报以下错误,有时候能正常执行?
org.apache.ibatis.binding.BindingException: Parameter 'id' not found. Available parameters are [arg1, arg2, param1, param2].

异常信息中的arg1、arg2是JDK编译出的参数名,param1、param2是MyBatis根据参数位置自动生成的参数名称。

问题原因在于映射方法定义的参数名id、name被编译为arg1、arg2,导致MyBatis默认根据arg1、arg2无法匹配参数。

JDK默认会将代码中的变量名,编译为arg1、arg2等。在JDK8及以后的版本中,编译时可以设置-parameters参数,使编译后参数名仍使用定义的参数名。

另一方面IDEA在Java Compiler配置中默认启用了-parameters参数,所以不加@Param也能自动按参数名匹配。

jdbcType的作用

  1. SQL语句中的jdbcType
select id from user where id = #{id,jdbcType=NUMERIC}

JDBC 要求,如果一个列允许使用 null 值,并且会使用值为 null 的参数,就必须要指定 JDBC 类型(jdbcType)。阅读 PreparedStatement.setNull()的 JavaDoc 来获取更多信息。

  1. resultmap中的jdbcType
<resultmap type="User" id="BaseResultMap">
  <id property="id" column="ID" jdbcType="DECIMAL"/>
</resultmap>

当数据库字段值为 NULL 时,数据库驱动可能无法返回准确的类型信息,MyBatis 也无法通过 NULL 值推断其实际类型。此时如果不指定 jdbcType,可能导致类型转换异常。

映射方法是否会返回null

  1. 返回单个对象时,可能返回null
User selectUserById(Long id);
  1. 返回对象集合时,不会返回null
List<User> selectUsersByIds(List<Long> ids);