where id = #{id}和where id = #{id,jdbcType=BIGINT}有什么区别

137 阅读2分钟

在 MyBatis 中,where id = #{id}where id = #{id,jdbcType=BIGINT} 都是用来设置 SQL 参数的写法,但它们之间有一些细微的区别,主要体现在类型处理数据库兼容性方面。

✅ 一、基本语法说明

MyBatis 使用 #{xxx} 语法表示这是一个参数占位符,底层会使用 PreparedStatement 设置参数。

1. where id = #{id}

这是最常用的写法,MyBatis 会自动推断参数的 JDBC 类型(jdbcType) ,根据 Java 类型来决定如何设置参数。

例如:

java
深色版本
User user = userMapper.selectById(123L);

如果 idLong 类型,MyBatis 可能会推断为 BIGINT


2. where id = #{id,jdbcType=BIGINT}

这个写法显式指定了参数的 JDBC 类型为 BIGINT

sql
深色版本
where id = #{id,jdbcType=BIGINT}

即使 Java 类型是 Long,也明确告诉 MyBatis:这个参数要以 BIGINT 类型来处理。


✅ 二、区别详解

特性#{id}#{id,jdbcType=BIGINT}
是否显式指定 JDBC 类型
MyBatis 如何处理自动推断按指定类型处理
安全性可能因类型推断错误导致异常更加明确,避免歧义
兼容性一般没问题,但某些数据库可能出错更兼容,特别是对 NULL 或复杂类型
推荐场景简单场景,类型明确复杂场景、NULL 值、多数据库兼容

✅ 三、为什么要显式指定 jdbcType?

  1. 当参数可能为 null 时
    MyBatis 无法自动推断 null 值的类型,必须显式指定 jdbcType,否则会抛出异常:

    java
    深色版本
    Caused by: org.apache.ibatis.type.TypeException: Error setting null for parameter #...
    

    正确写法:

    sql
    深色版本
    where id = #{id,jdbcType=BIGINT}
    
  2. 不同数据库对类型敏感
    例如 Oracle 和 MySQL 对整型的处理方式不同,显式指定可以避免类型不匹配问题。

  3. 提升代码可读性和可维护性
    显式指定类型可以让其他开发者更清楚地知道字段类型。


✅ 四、常见 jdbcType 对应关系

Java 类型jdbcType 推荐值
Long / longBIGINT
Integer / intINTEGER
StringVARCHAR
LocalDateDATE
LocalDateTimeTIMESTAMP
BigDecimalDECIMAL
BooleanBIT 或 BOOLEAN

✅ 五、示例对比

示例 1:自动推断(不推荐用于可为 null 的参数)

sql
深色版本
select * from user where id = #{id}

如果传入的 idnull,MyBatis 会抛异常。

示例 2:显式指定类型(推荐)

sql
深色版本
select * from user where id = #{id,jdbcType=BIGINT}

即使 idnull,也不会报错,MyBatis 会使用 setNull 方法。


✅ 六、总结

写法是否推荐说明
#{id}✅ 适用于简单场景,参数不为 null自动推断类型,简洁
#{id,jdbcType=BIGINT}✅✅ 推荐写法明确类型,兼容性好,适合 null 值或复杂场景

如果你使用的是 MyBatis Plus 或者 Spring Boot + MyBatis,建议在 Mapper XML 中统一使用 jdbcType 显式指定类型,特别是在涉及 null 值时,避免不必要的运行时错误。