在执行SQL时MyBatis会自动通过对象中的属性给SQL中参数赋值,它会自动将Java类型转换成数据库的类型。而一旦传入的是null它就无法准确判断这个类型应该是什么,就有可能将类型转换错误,从而报错。所以我们这样做。
疑问来自于,有时候Mapper.xml中,下面都可以用。
id = #{id,jdbcType=INTEGER} id = #{id}
那么问题来了!
Mybatis中什么时候应该声明jdbcType?
一般情况下,两种写法都可以。它们都可以获取Dao层传递过来的参数。
但是,当传入的参数为null时,需要指定jdbcType的类型,否则mybatis无法解析。
#{property, jdbcType=VARCHAR}
如果一个列允许 null 值,并且会传递值 null 的参数,就必须要指定 JDBC Type
如果是一个可以为null的字段,在insert的时候,没有给该字段赋值,mybatis就会报下面的错误
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.type.TypeException: Could not set parameters for mapping: ParameterMapping{property='__frch_item_0.defaultValue', mode=IN, javaType=class java.lang.String, jdbcType=null, numericScale=null, resultMapId='null', jdbcTypeName='null', expression='null'}. Cause: org.apache.ibatis.type.TypeException: Error setting null for parameter #6 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型: 1111 at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77) Caused by: org.apache.ibatis.type.TypeException: Error setting null for parameter #6 with JdbcType OTHER . Try setting a different JdbcType for this parameter or a different jdbcTypeForNull configuration property. Cause: java.sql.SQLException: 无效的列类型: 1111 at org.apache.ibatis.type.BaseTypeHandler.setParameter(BaseTypeHandler.java:47) at org.apache.ibatis.scripting.defaults.DefaultParameterHandler.setParameters(DefaultParameterHandler.java:87) ... 54 more Caused by: java.sql.SQLException: 无效的列类型: 1111
当Mybatis不能自动识别你传入对象的类型时。

所以要解决这个问题,需要针对这些可能为空的字段,手动指定其转换时用到的类型。
一般情况下,我们没有必要按个字段去识别/判断它是否可以为空,而是将所有的字段都当做可以为空,全部手动设置转换类型。
<update id="updateByPrimaryKey" parameterType="com.funyan.User" > update user set user_name = #{userName,jdbcType=VARCHAR}, user_pass = #{userPass,jdbcType=VARCHAR}, user_nickname = #{userNickname,jdbcType=VARCHAR}, user_email = #{userEmail,jdbcType=VARCHAR}, user_url = #{userUrl,jdbcType=VARCHAR}, user_avatar = #{userAvatar,jdbcType=VARCHAR}, user_last_login_ip = #{userLastLoginIp,jdbcType=VARCHAR}, user_register_time = #{userRegisterTime,jdbcType=TIMESTAMP}, user_last_login_time = #{userLastLoginTime,jdbcType=TIMESTAMP}, user_status = #{userStatus,jdbcType=INTEGER} where user_id = #{userId,jdbcType=INTEGER} </update>
附:Mybatis中 javaType 和 jdbcType 对应关系
JDBCType JavaType CHAR String VARCHAR String LONGVARCHAR String NUMERIC java.math.BigDecimal DECIMAL java.math.BigDecimal BIT boolean BOOLEAN boolean TINYINT byte SMALLINT short INTEGER int BIGINT long REAL float FLOAT double DOUBLE double BINARY byte[] VARBINARY byte[] LONGVARBINARY byte[] DATE java.sql.Date TIME java.sql.Time TIMESTAMP java.sql.Timestamp CLOB Clob BLOB Blob ARRAY Array DISTINCT mapping of underlying type STRUCT Struct REF Ref DATALINK java.net.URL