一个很神奇的BUG

需求:模糊查base_common_set这张基础数据集表,拿到国家列表数据。

基础SQL如下:

SELECT
            bcs.common_set_id as commonSetId,
            bcs.superior_id as superiorId,
            bcs.code as code,
            bcs.code3 as code3,
            bcs.cn_name as cnName
        FROM
            basedata_common_set bcs
        WHERE
            bcs.superior_id = 2
            AND bcs.is_deleted = 0
        <if test="keys != null and keys != ''">
            AND bcs.cn_name like concat('%', #{keys}, '%')
        </if>
            ORDER BY bcs.common_set_id DESC
            LIMIT 10

APIPost测试:

企业微信截图_9e4bf43b-612b-4ce7-8647-2907cf863615.png

返回结果为空
企业微信截图_948ede57-1606-4929-9315-3792fc2d3161.png

尝试缩小问题范围:取消这个like模糊匹配:

SELECT
            bcs.common_set_id as commonSetId,
            bcs.superior_id as superiorId,
            bcs.code as code,
            bcs.code3 as code3,
            bcs.cn_name as cnName
        FROM
            basedata_common_set bcs
        WHERE
            bcs.superior_id = 2
            AND bcs.is_deleted = 0
        <!--<if test="keys != null and keys != ''">
            AND bcs.cn_name like concat('%', #{keys}, '%')
        </if>-->
            ORDER BY bcs.common_set_id DESC
            LIMIT 10

企业微信截图_866532b8-8863-4695-a349-bc0d840f2cc5.png

可以看出可以查出结果。

再次尝试打开模糊查询,更换一个字段进行模糊查询:将cn_name 换成 en_name,查询条件不变

SELECT
            bcs.common_set_id as commonSetId,
            bcs.superior_id as superiorId,
            bcs.code as code,
            bcs.code3 as code3,
            bcs.cn_name as cnName,
               bcs.en_name
        FROM
            basedata_common_set bcs
        WHERE
            bcs.superior_id = 2
            AND bcs.is_deleted = 0
        <if test="keys != null and keys != ''">
            AND bcs.en_name like concat('%', #{keys}, '%')
        </if>
            ORDER BY bcs.common_set_id DESC
            LIMIT 10

如下:发现能查到数据,但是数据是不正确的,没有中字匹配值。
初步定位为:这个SQL可以匹配到数据,不是这个SQL语法的问题

企业微信截图_01809622-5be8-4b4e-adfb-9d5c5ecc3830.png

继续将SQL改回来,查cn_name列,使用英文关键字模糊查询

在数据库的一条记录上,在cn_name字段列增加一个字母Jpa用于测试:

企业微信截图_d6c436f2-01cc-406f-b832-87f1d8f225bb.png

可以发现,这条被修改的数据可以查出来:
企业微信截图_41c4f2a9-05e5-4c64-b6e6-b01f4e819442.png

最后测试使用等值中文匹配:cnName = #{keys},也查不出来。

综上,定位为Mybatis无法在该表进行中文匹配。

且Mybatis控制台输出的SQL,放到数据库可以模糊或等值匹配出来,但是Mybatis本身不能查出数据,猜想:数据库层面SQL已经查出来结果,但是结果无法被Mybatis解析,所以为null。

查过一些解决方案:
结果集字段映射- 修改后无效
字符集编码- 修改后无效

有什么其他的方法吗?大哥们。

数据库url:
jdbc:mysql://地址:3306/数据库?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8

----- 下面是Mybatis控制台输出的SQL

SELECT
    bcs.common_set_id AS commonSetId,
    bcs.superior_id AS superiorId,
    bcs.CODE AS CODE,
    bcs.code3 AS code3,
    bcs.cn_name AS cnName 
FROM
    basedata_common_set bcs 
WHERE
    bcs.superior_id = 2 
    AND bcs.is_deleted = 0 
    AND bcs.cn_name LIKE concat( '%', '中', '%' ) 
ORDER BY
    bcs.common_set_id DESC 
    LIMIT 10;

Mybatis控制台
企业微信截图_fe3bee0c-70fe-4923-97be-2d86677600dc.png

放到数据库查询,可以查出来:

企业微信截图_e17ee60a-1ddf-4c77-9e93-11b446b2f431.png

阅读 2.6k
3 个回答

jdbc:mysql://地址:3306/数据库?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8

characterEncoding写到最前试试

你的like语句,能否在java程序中自己先拼好再传参数,mysql中直接使用concat函数有时候会影响效率,尽量不要直接用sql语句的函数

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题