今天在工作中遇到一个问题:在MyBatis的Mapper中增加了一个长度为1的字符串的判断,但是程序执行的时候报了类型转换错误异常,很纳闷,最后用了两个小时才找到问题所在,具体情况是这样的:

        我们通常在Mapper中会有动态的判断,比如判断某个变量是否为空或者是否等于特定的一些值,比如:

<!-- 判断空串 -->
<if test=" PARAM != '' and PARAM != null">
    ...<!-- 如果满足条件将执行的语句 -->
</if>
<!-- 判断PARAM的值是否为字符串HELLO -->
<if test=" PARAM == 'HELLO'">
    ...<!-- 如果满足条件将执行的语句 -->
</if>

我们都这样使用的不亦乐乎,也没有发现什么不对头的地方。

但是我今天再具体业务中,需要判断参数是否为字符串“-”,我的写法:

<if test=" PARAM == '-'">
    ...<!-- 如果满足条件将执行的语句 -->
</if>

入参的时候PARAM中传的值为字符串“test”看上去是没有问题的,但是程序运行起来,执行这里的判断语句的时候,程序报错,信息如下:

Caused by: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
	### Error querying database.  Cause: java.lang.NumberFormatException: For input string: "test"
	### Cause: java.lang.NumberFormatException: For input string: "test"
	    at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:79)
	    at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:447)
	    at com.sun.proxy.$Proxy93.selectList(Unknown Source)
	    at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:231)
	    at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:128)
	    at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:68)
	    at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:53)
	    at com.sun.proxy.$Proxy126.getKidneyDiseaseFileList(Unknown Source)
	    ... 135 common frames omitted

从报错信息可以看出是说类型转换错误,String不能转换成number。

一下是我处理的过程:

把焦点聚集在类型转换上面的时候,就一直在数据库类型上面徘徊,浪费了一些时间,其实这里是不应该一直在一个点上反复停留的。

老司机的这种解决问题的方法挺值得我学习。

    3. 老司机因为忙其它任务,就忙去了,我接下来也采取定位的方法找问题所在,最后把问题的焦点,定位在了那条判断语句上面,因为那个判断参数是否为字符串“-”是我后来加上去的,所以我意识到问题就在这里。但是还是不知道怎么错了。

    4. 这是旁边站着一位热心的同事,在一起看这个问题,他说可能是单个字符串,就把它转换成ASCII编码了,所以和传递进来的字符串进行比较的时候,就需要先转成数字类型的,所以就报出了这个错误。虽然仅仅是一种猜想,但是同事说,把这个“-”换成其它的单个字符应该也会报错,但是换成长度大于1的字符串就不会报错了,我修改了一下,进行了测试,果然是这样。

    5. 最后我就重新修改了写法。问题解决掉了。把横杠写成两个,变成字符串。这样就不会进行转换了。或者还有一种写法,就是把外层用单引号。里面使用双引号,这样我自己经过测试是可以的。

<!-- 判断PARAM的值是否为字符串HELLO -->
<if test=' PARAM == "-"'>
    ...<!-- 如果满足条件将执行的语句 -->
</if>

我个人觉得这可能和xml的解析字符串有关,之后需要做一点功课,找一下xml解析方面的资料进一步确认和探究一下。

这个过程中我自己犯了一个错误:找到一点信息,进行了确认之后,还一直停留在这个信息上面,没有往其它的方面去想。浪费了一些时间。

过程中学习到的:

    1. 问题出现了,如果凭借已有经验解决不了问题,甚至连问题出在什么地方都没办法确定的时候,应该首先确定问题出现的精确位置。删减法不失为一种好的方法;