使用Mybatis查询的二进制类型的数据时候导致转码错误 , 数据库隐式处理

在使用Mybatis进行mysql数据查询的时候 , 因为给前端返回的数据要使用 CONCAT 函数拼接起来, 从而出现了一个bug 在这里插入图片描述

然后主要的sql是

select t.id,
                        CONCAT(
                (SELECT COUNT(1) FROM t_aqjcjl_jcjg g WHERE g.task_id = t.id AND g.jcjl = '3'),
                '/',
                (SELECT COUNT(1) FROM t_aqjcjl_jcjg g WHERE g.task_id = t.id AND g.jcjl = '2'),
                '/',
                (SELECT COUNT(1) FROM t_aqjcjl_jcjg g WHERE g.task_id = t.id AND g.jcjl = '1')
                ) AS wjyczc
                from t_aqjcjl_task t

在DBeaver中执行之后发现数据的类型变成了VarBinary的类型 , 经过查阅得知是二进制类型,导致的二进制转换的base64的乱码。

在这里插入图片描述

可能的原因

子查询结果为 NULL

在 concat 函数里,要是任何一个子查询的结果为 NULL,那么 concat 函数的整个结果就会是 NULL。例如,当 t_aqjcjl_jcjg 表中不存在满足 g.task_id = t.id 且 g.jcjl = ‘3’ 条件的记录时,(select count(1) from t_aqjcjl_jcjg g where g.task_id = t.id and g.jcjl = ‘3’ ) 的结果就是 0,这本身没问题,但如果查询过程中因为某些原因返回 NULL,就会导致 concat 函数结果为 NULL。
不过在明确知道结果不为null的情况下查询结果也是相同
在这里插入图片描述

解决办法

使用 IFNULL 处理 NULL 值

加上ifnull之后这一列的值变成了正常的的字符串
加上ifnull之后这一列的值变成了正常的的字符串

原理探究

经过查阅资料和验证 , 在 SQL 查询中,当子查询可能返回 NULL 时,数据库引擎会隐式处理类型推断,而 IFNULL(或 COALESCE)函数会强制指定一个明确的类型。

确切的原因

  1. 子查询返回 NULL 时的类型不确定性

    • 当子查询 (SELECT COUNT(1) FROM …) 没有匹配的行时,结果会返回 NULL(而不是 0)。
    • 如果直接使用子查询结果(不加 IFNULL),某些数据库(如 MySQL)会将字段类型推断为 BINARY 或 VARBINARY,因为 NULL 的类型可能无法明确推断为数值类型。
  2. CONCAT 函数对类型的隐式转换

    • CONCAT 会将所有参数隐式转换为字符串,但如果子查询结果可能为 NULL,某些数据库会因类型不确定性将其视为二进制类型,而非字符串。
  3. MyBatis 对二进制类型的处理

    • 如果数据库返回 BINARY 类型,MyBatis 可能将其误判为二进制数据(如 BLOB),进而进行 Base64 编码,导致最终值显示为乱码(如 OS8wLzA=)。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值