MyBatis错误

说明:记录一次MyBatis错误,错误信息如下,说数字转换异常,显然,把一个字符串类型转为数字类型,肯定是不行的。

text 复制代码
2024-08-29 19:44:43.198 ERROR 24216 --- [nio-9090-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database.  Cause: java.lang.NumberFormatException: For input string: "hezy"
### Cause: java.lang.NumberFormatException: For input string: "hezy"] with root cause

java.lang.NumberFormatException: For input string: "hezy"

场景

(前端)

(接口)

java 复制代码
    @GetMapping("/test")
    public void test() {
        User user = new User();
        user.setId(1);
        user.setUsername("hezy");
        userRepository.selectUserById(user);
    }

(Repository)

java 复制代码
    User selectUserById(@Param("user") User user);

定位到项目的动态SQL,如下,这是我本地复现的Demo,在实际的项目中,是一个查询条件字段,表示某个分组,可选"所有分组"或者"具体某个分组",当时的开发应该是和前端约定过,当值为0时表示为所有分组,所以这个字段传递可能是0,或者是具体的分组ID,因此就有了类似下面这样的判断

(动态SQL)

xml 复制代码
    <select id="selectUserById" resultType="com.hezy.pojo.User">
        SELECT * FROM i_users WHERE id = #{user.id}
        <if test="user.username != null and user.username != '' and user.username != '0'">
            and username = #{user.username}
        </if>
        <if test="user.username == '0'">
            and username = '0'
        </if>
    </select>

分析&解决

显然,这里是有隐型的类型转换,但一眼看过去,动态SQL里面的判断都是字符串,0也用单引号包起来了。无计可施之际,我想到单引号在Java中表示的是字符,而字符又能自动转为数字进行计算,如下,所以我想是不是MyBatis底层把'0'当做数字了,然后把左边的参数也尝试转为数值类型,造成了这次错误。

于是,我想到把0通过双引号包起来,这铁定就是字符串了,双引号在XML里面需要通过&quot;转义,如下:

xml 复制代码
    <select id="selectUserById" resultType="com.hezy.pojo.User">
        SELECT * FROM i_users WHERE id = #{user.id}
        <if test="user.username != null and user.username != '' and user.username != &quot;0&quot;">
            and username = #{user.username}
        </if>
        <if test="user.username == &quot;0&quot;">
            and username = '0'
        </if>
    </select>

成功了,golder~,这个问题困扰了很久

解决 :if标签里面对数值的判断,如果你想要的是判断字符串,右边的数值需要用&quot;包起来。

相关推荐
陈随易1 小时前
Postman 被曝自动往 Claude Code 和 Codex 装插件
前端·后端·程序员
AI你一生一世3 小时前
不止于时序存储:DolphinDB 如何成为 AI 时代的工业智能底座
java·人工智能·struts·时序数据库·工业智能·dolphindb·ai基础设施
云-缩影3 小时前
拆解 AI 图像生成应用的后端架构:ECS、OSS 和大模型 API 怎么配合
java·spring boot·后端
瑞克-桑切斯3 小时前
7、MySQL 慢查询排查与优化实战指南
java·服务器·数据库
考虑考虑4 小时前
Posrgresql恢复.backup文件
数据库·后端·postgresql
无奈何杨4 小时前
风控决策系统决策流,策略模式,权重、顺序、投票、最坏
后端
Patrick_Wilson6 小时前
Go 为什么需要 defer?从函数怎么收尾说起
后端·go·编程语言
苏三说技术6 小时前
DeepSeek Harness入驻B站,评论区被干成了大型插件集市!
后端
橙序员小站6 小时前
我一句话让 AI 把公众号工作台搭完了:部署实测记录
后端
Patrick_Wilson6 小时前
从文本输出理解 Go 方法与接口
后端·go·编程语言