解决MyBatis报错“Error querying database. Cause: java.lang.NumberFormatException”错误
今天就和大家分享一次我遇到的“Error querying database. Cause: java.lang.NumberFormatException: For input string: “xxx””错误,以及我的解决办法,希望能给遇到类似问题的朋友提供一些帮助。这个错误和MySql以及Java开发都有关系,下面我们就一步步来分析。
一、错误信息及相关代码
报错信息如下:
org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.NumberFormatException: For input string: "A" ### Cause: java.lang.NumberFormatException: For input string: "A" at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:96) ~[mybatis-spring-2.0.6.jar:2.0.6]
出现错误的代码片段是这样的:
List<Detail> queryByFloorNo(@Param("floorNo") String floorNo);
对应的SQL语句部分如下:
<if test="floorNo
== 'A'"> AND LEFT(PHY_SYS_TYPE, 1) IN ('A', 'L') </if>
这个SQL语句的作用是根据传入的floorNo参数值来筛选数据,但是在执行的时候却报了NumberFormatException
错误。
二、问题原因剖析
之所以出现这个错误,和MyBatis使用的OGNL(Object – Graph Navigation Language)语法有关。OGNL是MyBatis用于在XML映射文件中编写动态SQL查询和映射规则的表达式语言 。在Java语言里,有个特性:单引号括起来的单个字符,比如'Y'
,会被当作char
类型处理;而单引号括起来的多个字符,像'AA'
,或者双引号括起来的单个字符,比如"A"
,则会被视为String
类型。MyBatis在解析OGNL表达式时,遵循了Java语言的这个规则。
在我们的报错场景中,filterStatus
参数原本应该是String
类型,但是当我们在SQL语句中使用floorNo== 'A'
这样的表达式时,MyBatis会把'A'
默认解析成char
类型。这就导致在后续处理过程中,如果涉及到类型转换,比如将这个值和数据库中的字段进行比较,就可能出现问题。因为数据库中的字段类型可能和MyBatis解析后的类型不匹配,从而引发NumberFormatException
错误,也就是在将字符转换成数字时出现了问题。
三、解决方案汇总
找到了问题的根源,接下来就是解决问题啦。我尝试了几种方法,都成功解决了这个错误,下面分享给大家。
(一)外侧使用单引号,单字符使用双引号
这是一种比较简单直接的方法。我们只需要修改SQL语句中的表达式,将单字符用双引号括起来,外侧使用单引号。修改后的SQL语句如下:
<if test='floorNo== "A"'> AND LEFT(PHY_SYS_TYPE, 1) IN ('A', 'L') </if>
这样,MyBatis在解析时,就会把"A"
正确地识别为String
类型,避免了类型不匹配的问题。
(二)用toString()转成字符串
我们还可以通过调用toString()
方法,将单字符强制转换为字符串。修改后的SQL语句如下:
<if test="floorNo== 'A'.toString()"> floorNo = #{floorNo} </if>
这种方式明确地告诉MyBatis,这里的'A'
应该被当作字符串来处理,同样可以解决类型解析错误的问题。
(三)加转义实体字符串引号
另外一种方法是使用转义实体字符串引号"
。修改后的SQL语句如下:
<if test='floorNo== "A"'> floorNo = #{floorNo} </if>
使用转义字符后,MyBatis也能正确识别这些字符为字符串类型,从而避免错误的发生。
通过这几种方法,都可以有效地解决“Error querying database. Cause: java.lang.NumberFormatException”这个错误。在实际开发中,遇到问题时我们要仔细分析错误信息,结合相关技术的原理来寻找解决方案。希望我的经验能对大家有所帮助,如果还有其他疑问,欢迎在评论区留言讨论。