开发者

MyBatis Plus like参数为百分号%查询结果异常原因分析及解决

开发者 https://www.devze.com 2025-09-25 10:34 出处:网络 作者: _院长大人_
目录问题分析问题出现的情况解决方案方法 1:去除%,只匹配真实字符(不推荐)方法 2:使用eq()进行精确匹配(适用于完全匹配查询)方法 3:使用转义%(推荐本次使用)**Java 代码SQL 解析修改后执行结果最佳实践推荐
目录
  • 问题分析
    • 问题出现的情况
  • 解决方案
    • 方法 1:去除%,只匹配真实字符(不推荐)
    • 方法 2:使用eq()进行精确匹配(适用于完全匹配查询)
    • 方法 3:使用转义%(推荐本次使用)**
      • Java 代码
      • SQL 解析
      • 修改后执行结果
  • 最佳实践推荐
    • 总结

      在日常开发中,我们经常使用 MyBATis Plus 进行数据库查询。其中,LIKE 关键字用于模糊匹配,但如果用户输入的查询条件包含 %,可能会导致查询结果异常。

      如下图,数据库里面是没有%的plate_number数据的,但是查询出86条数据

      MyBatis Plus like参数为百分号%查询结果异常原因分析及解决

      问题分析

      我们来看一段 MyBatis Plus 的查询代码:

      queryWrapper
          .like(StringUtils.hasText(reqVo.getPlateNumber()), HlCar::getPlateNumber, reqVo.getPlateNumber())
          .like(StringUtils.hasText(reqVo.getVin()), HlCar::getVin, reqVo.getVin())
          .like(StringUtils.hasTextjs(reqVo.getModelName()), HlCar::getCarSeries, reqVo.getModelName());
      

      该代码的意图是:

      • 如果 reqVo.getPlateNumber()reqVo.getVin()reqVo.getModelName()非空,则执行 LIKE 查询。
      • 例如,用户输入 "ABC",SQL 语句应为:
      SELECT * FROM hl_car WHERE plate_number LIKE '%ABC%'
      

      这样可以查询出包含 "ABC" 的所有车牌。

      问题出现的情况

      • 如果用户输入了 %,如 "%",SQL 会变成:
      SELECT * FROM hl_car WHERE plate_number LIKE '%%%'
      

      由于 % 在 SQL LIKE 语句中是通配符,它会匹配任意字符,这可能导致匹配出比预期更多的数据。

      • 如果用户仅输入 %,则 LIKE '%%%' 会匹配所有数据,完全失去筛选作用。

      查询结果不符合预期,可能导致:

      1. 查询数据量过大,影响系统性能。
      2. 业务逻辑错误,返回了不相关的数据。

      解决方案

      方法 1:去除%,只匹配真实字符(不推荐)

      一种简单的方式是移除 %,让 LIKE 只匹配实际输入的内容。

      String plateNumber = reqVo.getPlateNumber() != null ? reqVo.getPlateNumber().replace("%", "").trim() : null;
      String vin = reqVo.getVin() != null ? reqVo.getVin().replace("%", "").trim() : null;
      String modelName = reqVo.getModelName() != null ? reqVo.getModelName().replace("%", ""http://www.devze.com).trim() : null;
      
      queryWrapper
      .like(StringUtils.hasText(plateNumber), HlCar::getPlateNumber, plateNumber)
      .like(StringUtils.hasTe编程客栈xt(vin), HlCar::getVin, vin)
      .like(StringUtils.hasText(modelName), HlCar::getCarSeries, modelName);
      

      缺点

      • 如果用户查询 "100%ABC",会变成 "100ABC",查询结果不准确。
      • 失去了 % 作为普通字符的意义,不能搜索包含 % 的数据。

      方法 2:使用eq()进行精确匹配(适用于完全匹配查询)

      如果 plateNumber 是用户完整输入的车牌号,VIN 码和 车型名 也是完整的,则可以使用 eq()

      queryWwww.devze.comrapper.eq(StringUtils.hasText(plateNumber), HlCar::getPlateNumber, plateNumber)
      .eq(StringUtils.hasText(vin), HlCar::getVin, vin)
      .eq(StringUtils.hasText(modelName), HlCar::getCarSeries, modelName);
      

      优点

      • 精准匹配,不会因为 % 影响查询结果。
      • 适用于 VIN 码、车牌号等完整匹配的查询

      缺点

      • 不能进行模糊匹配,用户必须输入完整的车牌号或 VIN 才能查到数据。

      方法 3:使用转义%(推荐本次使用)**

      %_使用escapeLike方法转义转义

      Java 代码

      // 处理 LIKE 查询参数,转义 % 和 _
      String escapeLike(String str) {
      return str != null ? str.replace("%", "\\%").replace("_", "\\_").trim() : null;
      }
      
      // 转义参数
      String plateNumber = escapeLike(reqVo.getPlateNumber());
      String vin = escapeLike(reqVo.getVin());
      String modelName = escapeLike(reqVo.getModelName());
      
      // 避免 `null` 参数
      if (StringUtils.hasText(plateNumber)) {
          queryWrapper.like(HlCar::getPlateNumber, plateNumber);
      }
      if (StringUtils.hasText(vin)) {
          queryWrapper.like(HlCar::getVin, vin);
      }
      if (StringUtils.hasText(modelName)) {
          queryWrapper.like(HlCar::getCarSeries, modelName);
      }
      

      SQL 解析

      如果用户输入 "100%ABC",SQL 语句会变成:

      SELECT * FROM hl_car WHERE plate_number LIKE '100\%ABC'
      
      • %% 变成普通字符,不再作为通配符。
      • 这样可以正确匹配 100%ABC,而不会匹配 100XYZABC

      优点

      • 支持python模糊查询,但不会误匹配。
      • 不会影响查询数据的完整性,能够正确匹配包含 % 的车牌号或 VIN。

      修改后执行结果

      • 可以看到查询正常了
      • 在这里插入图片描述

      MyBatis Plus like参数为百分号%查询结果异常原因分析及解决

      MyBatis Plus like参数为百分号%查询结果异常原因分析及解决

      最佳实践推荐

      方法适用场景是否支持 %

      作为普通字符

      是否支持模糊匹配
      方法 1:去掉%适用于只需要模糊查询的情况❌(去掉 %

      影响查询结果)

      方法 2:用 eq()

      精确匹配

      适用于 VIN 码、完整车牌匹配
      方法 3:用 ESCAPE

      转义(推荐)

      适用于所有 LIKE 查询

      综合来看,方法 3(使用 ESCAPE)是最优解,兼顾了模糊匹配和 % 作为普通字符的问题。

      总结

      在 MyBatis Plus LIKE 查询时,如果 plateNumbervinmodelName 含有 %,会导致误匹配。

      直接 LIKE '%' 会查询所有数据,可能影响业务逻辑。

      解决方案:

      1. 去掉 %(不推荐)
      2. 改用 eq() 精确匹配(适用于完整匹配)
      3. 使用 ESCAPE 转义 %(推荐)

      正确使用 LIKE 查询,能避免数据误匹配,提高查询准确性和系统性能!

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持编程客栈(www.devze.com)。

      0

      精彩评论

      暂无评论...
      验证码 换一张
      取 消

      关注公众号