进行批量更新时,需要是布尔类型的字段,包含true/false和0/1,这个会被Mybatis自动转为数据库(mysql)和java实体对象中的布尔类型
<!-- Boolean类型特殊处理 --> <when test="fieldName == 'isScrap'"> SET is_scrap = <choose> <when test="value == 'true' || value == '1'"> 1 </when> <otherwise> 0 </otherwise> </choose> </when>堆栈跟踪:
MyBatis XML 中的 OGNL 表达式 value == '1',在 OGNL 里 单引号包裹单个字符 '1' 被解析为 char 类型,而非 String。当 value 是 "false" 时,OGNL 比较 String 与 char,会触发 compareWithConversion 尝试将两者都转为数值(double)比较,于是 Double.parseDouble("false") 抛出 NumberFormatException。
value = "false" (String) '1' = char 类型 OGNL: String == char ? → compareWithConversion() → 尝试将 "false" 转为 double → NumberFormatException (错误)NumberFormatException: For input string: "false" at OgnlOps.doubleValue() ← OGNL 尝试把 "false" 转成数字 at OgnlOps.compareWithConversion() ← OGNL 类型转换比较 at OgnlOps.isEqual() ← == 比较 at ASTEq.getValueBody() ← value == '1' 这个节点 at ASTOr.getValueBody() ← or 运算符【注意】
使用 单引号 情况下,当传递的是 true / false 是没有问题的,传递时会被认定为字符串,但是传递 0/1 会被认定为是 char类型,需要使用 双引号 进行包裹,但是在MyBatis的xml配置文件中,基本上会用 双引号 来包裹最外层的内容,那么在双引号里面就只能使用单引号了,这样又会出现错误,那么就需要使用转义符进行识别:"
修改后的代码:
<!-- Boolean类型特殊处理 --> <when test="fieldName == 'isScrap'"> SET is_scrap = <choose> <when test="value == 'true' or value == "1""> 1 </when> <otherwise> 0 </otherwise> </choose> </when>这样无论 value 是 "true"、"false"、"1"、"0" 还是其他字符串,都是同类型(String vs String)的 equals 比较,不会再触发 NumberFormatException。