当前位置: 首页 > news >正文

MyBatis进行模糊查询时SQL语句拼接引起的异常问题

项目场景:

模糊查询CRM项目,本文遇到的问题是在实现根据页面表单中输入条件,在数据库中分页模糊查询数据,并在页面分页显示的功能时,出现的“诡异”bug。
开发环境如下:
操作系统:Windows11
Java:jdk-21.0.2
IDE:eclipse 2024-3R
Tomcat:apache-tomcat-10.1.11
Maven:apache-maven-3.9.6
数据库:MariaDB11.0
项目地址:https://gitcode.com/weixin_44803446/crm-project.git


问题描述

在项目中,通过一下两个查询,分别查询对象列表跟总条数,通过日期查询及空条件查询结果均无异常,但是在通过名称及所有者名称进行模糊查询时,返回的查询结果为0,即使是全字段匹配也无法正常查询到想要的数据,Mapper文件片段如代码所示:

<!-- 通过条件查询市场活动表 --><select id="selectActivityListByConditionForPage" parameterType="map" resultMap="BaseResultMap">select a.id, a.name, u1.name as owner, a.start_date, a.end_date, a.cost, u2.name as create_by, a.create_timefrom tbl_activity ajoin tbl_user u1 on a.owner = u1.idjoin tbl_user u2 on a.create_by = u2.id<where><if test="name != null and name !=''">and a.name like '%'#{name}'%'	       </if><if test="owner != null and owner != ''"> and u1.name like '%'#{owner}'%' </if><if test="startDate != null and startDate != ''"> and a.start_date &gt;= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date &lt;= #{endDate} </if></where>order by a.create_time desclimit #{beginNo},#{pageSize}</select><!-- 查询对应条件下的市场活动总条数 --><select id="selectActivityCounts" parameterType="map" resultType="int">select count(*)from tbl_activity ajoin tbl_user u1 on a.owner = u1.idjoin tbl_user u2 on a.create_by = u2.id<where><if test="name != null and name !=''">and a.name like '%'#{name}'%'           </if><if test="owner != null and owner != ''"> and u1.name like '%'#{owner}'%' </if><if test="startDate != null and startDate != ''"> and a.start_date &gt;= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date &lt;= #{endDate} </if></where></select>

原因分析:

  1. 首先,确定前端的字段是否完整的传递到Controller,通过Console.log(参数)的方式将参数打印在浏览器控制台中,经过验证参数传递无异常;
  2. 其次,在Controller及Service中获取参数并打印,确保参数传递过程没有缺失等;
  3. 查看查询日志:
JDBC Connection [org.mariadb.jdbc.Connection@5516cc8d] will be managed by Spring
==>  Preparing: select a.id, a.name, u1.name as owner, a.start_date, a.end_date,a.cost, u2.name as create_by, a.create_time from tbl_activity a join tbl_user u
1 on a.owner = u1.id join tbl_user u2 on a.create_by = u2.id WHERE a.name like '
%'?'%' order by a.create_time desc limit ?,?
==> Parameters: n(String), 0(Integer), 10(Integer)
<==      Total: 0
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSq
lSession@2ef7efff]
Transaction synchronization committing SqlSession [org.apache.ibatis.session.def
aults.DefaultSqlSession@2ef7efff]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.
defaults.DefaultSqlSession@2ef7efff]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaul
ts.DefaultSqlSession@2ef7efff]
Creating a new SqlSession
Registering transaction synchronization for SqlSession [org.apache.ibatis.sessio
n.defaults.DefaultSqlSession@66e3b3d0]
JDBC Connection [org.mariadb.jdbc.Connection@b60a270] will be managed by Spring
==>  Preparing: select count(*) from tbl_activity a join tbl_user u1 on a.owner 
= u1.id join tbl_user u2 on a.create_by = u2.id WHERE a.name like '%'?'%'
==> Parameters: n(String)
<==    Columns: count(*)
<==        Row: 0
<==      Total: 1
Releasing transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSq
lSession@66e3b3d0]
Transaction synchronization committing SqlSession [org.apache.ibatis.session.def
aults.DefaultSqlSession@66e3b3d0]
Transaction synchronization deregistering SqlSession [org.apache.ibatis.session.
defaults.DefaultSqlSession@66e3b3d0]
Transaction synchronization closing SqlSession [org.apache.ibatis.session.defaul
ts.DefaultSqlSession@66e3b3d0]

由数据库查询日志可以看出,在执行模糊查询时,参数准确无误的传递到了Sql语句中,但是经过模糊查询后,查到的数量Total为0,但是实际上数据库中是有一条符合模糊条件的数据的。
猜想:

<if test="name != null and name !=''">and a.name like '%'#{name}'%'	       
</if>

这一句模糊查询语句有问题,尝试在’%‘与#{name} 之间加上空格后重启服务器测试,发现模糊查询功能正常。问题就出在MyBatis在处理字符串拼接时,如果以’%‘#{name}’%’ 这样紧密的格式书写,则会导致其将整个字段识别为一个整体,最终的拼接体可能为%‘#{name}’%。


解决方案:

  1. 通过在#{name}前后添加空格,让MyBatis正确的识别并拼接参数与字符串;
  2. 更严谨的方式是使用CONCAT函数,通过CONCAT()函数将"%" 与#{name}拼接起来,这样避免了因为拼写错误等原因导致最终SQL与我们预想的不一致的情况。
<!-- 通过条件查询市场活动表 --><select id="selectActivityListByConditionForPage" parameterType="map" resultMap="BaseResultMap">select a.id, a.name, u1.name as owner, a.start_date, a.end_date, a.cost, u2.name as create_by, a.create_timefrom tbl_activity ajoin tbl_user u1 on a.owner = u1.idjoin tbl_user u2 on a.create_by = u2.id<where><if test="name != null and name !=''">and a.name like concat('%',#{name},'%')</if><if test="owner != null and owner != ''"> and u1.name like concat('%', #{owner},'%' )</if><if test="startDate != null and startDate != ''"> and a.start_date &gt;= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date &lt;= #{endDate} </if></where>order by a.create_time desclimit #{beginNo},#{pageSize}</select><!-- 查询对应条件下的市场活动总条数 --><select id="selectActivityCounts" parameterType="map" resultType="int">select count(*)from tbl_activity ajoin tbl_user u1 on a.owner = u1.idjoin tbl_user u2 on a.create_by = u2.id<where><if test="name != null and name !=''">and a.name like concat('%',#{name},'%')</if><if test="owner != null and owner != ''"> and u1.name like concat('%', #{owner},'%' )</if><if test="startDate != null and startDate != ''"> and a.start_date &gt;= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date &lt;= #{endDate} </if></where></select>

相关文章:

MyBatis进行模糊查询时SQL语句拼接引起的异常问题

项目场景&#xff1a; CRM项目&#xff0c;本文遇到的问题是在实现根据页面表单中输入条件&#xff0c;在数据库中分页模糊查询数据&#xff0c;并在页面分页显示的功能时&#xff0c;出现的“诡异”bug。 开发环境如下&#xff1a; 操作系统&#xff1a;Windows11 Java&#…...

网站调用Edge浏览器API:https://api-edge.cognitive.microsofttranslator.com/translate

Edge浏览器有自带的翻译功能&#xff0c;在运行pc项目可能会遇到疯狂调用Edge的API https://api-edge.cognitive.microsofttranslator.com/translate 这个URL&#xff08;https://api-edge.cognitive.microsofttranslator.com/translate&#xff09;指向的是微软服务中的API接…...

css实现优惠券样式

实现优惠券效果&#xff1a; 实现思路&#xff1a; 需要三个盒子元素&#xff0c;使用 css 剪裁&#xff0c;利用 ellipse 属性&#xff0c;将两个盒子分别裁剪成两个半圆&#xff0c;位置固定在另一个盒子元素左右两边适当位置上。为另一个盒子设置想要的样式&#xff0c;圆角…...

函数递归(C语言)(详细过程!)

函数递归 一. 递归是什么1.1 递归的思想1.2 递归的限制条件 二. 递归举例2.1 求n的阶乘2.2 按顺序打印一个整数的每一位 三. 递归与迭代3.1 求第n个斐波那契数 一. 递归是什么 递归是学习C语言很重要的一个知识&#xff0c;递归就是函数自己调用自己&#xff0c;是一种解决问题…...

uniapp 接口请求封装

根目录下创建 config目录 api.js request.js // request.js // 封装一个通用的网络请求函数 适当调整 function httpRequest(options) {const userToken uni.getStorageSync(access_token).token;return new Promise((resolve, reject) > {uni.request({url: ${options.ur…...

C++中的观察者模式

目录 观察者模式&#xff08;Observer Pattern&#xff09; 实际应用 股票价格监控系统 发布-订阅系统 总结 观察者模式&#xff08;Observer Pattern&#xff09; 观察者模式是一种行为型设计模式&#xff0c;它定义了对象间的一对多依赖关系。当一个对象的状态发生改变…...

conda虚拟环境,安装pytorch cuda cudnn版本一致,最简单方式

1、pytorch版本安装&#xff08;卸载也会有问题&#xff09; &#xff08;1&#xff09;版本如何选择参考和卸载 https://zhuanlan.zhihu.com/p/401931724 &#xff08;2&#xff09;对应版本如何安装命令 https://pytorch.org/get-started/previous-versions/ 最简答安装参考…...

第 5 章:面向生产的 Spring Boot

在 4.1.2 节中&#xff0c;我们介绍了 Spring Boot 的四大核心组成部分&#xff0c;第 4 章主要介绍了其中的起步依赖与自动配置&#xff0c;本章将重点介绍 Spring Boot Actuator&#xff0c;包括如何通过 Actuator 提供的各种端点&#xff08;endpoint&#xff09;了解系统的…...

在 Windows 操作系统中,可以通过命令行工具来杀死进程

1. 使用 taskkill 命令 taskkill 命令是一个用于终止进程的命令行工具&#xff0c;可以通过进程名称或进程 ID (PID) 来杀死进程。 按进程名称杀死进程 taskkill /IM processname.exe /Fprocessname.exe 是进程的名称。/F 参数表示强制终止进程。 例如&#xff0c;终止名为…...

uni-app文件下载 h5 xls 乱码 锟斤拷 Blob pdf打不开

原先下载方式&#xff0c;PC管理端和浏览器打开文件能下载&#xff0c;xls没出现乱码&#xff0c;pdf能正常显示,H5下载xls乱码锟斤拷&#xff0c;PDF显示空白内容 怀疑是前端问题&#xff0c;也尝试过修改后端代码 后端设置编码格式 response.setCharacterEncoding(characte…...

Vue25-内置指令02:v-text指令

一、v-html对比v-text v-html支持结构的解析&#xff0c;v-text不支持结构的解析。 二、v-html的安全性问题 2-1、cookie的原理&#xff08;node.js&#xff09; 7天免登录&#xff0c;cookie实现。 cookie的本质就是类似于json的字符串&#xff0c;格式是&#xff1a;key-va…...

stable diffusion中的negative prompt是如何工作的

https://stable-diffusion-art.com/how-negative-prompt-work/https://stable-diffusion-art.com/how-negative-prompt-work/https://zhuanlan.zhihu.com/p/644879268...

STM32项目分享:智能小区充电桩系统

目录 一、前言 二、项目简介 1.功能详解 2.主要器件 三、原理图设计 四、PCB硬件设计 1.PCB图 2.PCB板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片&#xff1a; 哔哩哔哩视频链接&#xff1a; https://www.bilibili.c…...

PDU模块中浪涌保护模块与空开模块的应用

由于PDU具体应用的特殊性&#xff0c;其在规划设计时具有应用场景的针对性&#xff0c;同时PDU的高度定制化的特点&#xff0c;是其他电气联接与保护产品所不具备的。 PDU基础的输出输入功能外&#xff0c;其电路的控制与电压保护器同时也极为重要。空气开关和浪涌保护器相关功…...

19、Go Gin框架集成Swagger

介绍&#xff1a; Swagger 支持在 Gin 路由中使用一系列注释来描述 API 的各个方面。以下是一些常用的 Swagger 注释属性&#xff0c;这些属性可以在 Gin 路由的注释中使用&#xff1a; Summary: 路由的简短摘要。Description: 路由的详细描述。Tags: 用于对路由进行分类的标…...

自动同步库数据——kettle开发36

kettle中的那些人工智能。 一、kettle的AI能力目录 跨库同步 2.自动开发 3.自动优化 二、AI实例 1、跨库同步 sqlsever表同步至oracle数据库 1.1源库sqlserver 1.2目标库oracle 1.3可视化跨库同步 使用多表复制向导 选择跨库的表&#xff0c;下一步下一步&#xff0c;即可…...

MSOCache在电脑中可以删除吗?

MSOCache文件夹在电脑中是可以删除的。但删除前需要了解以下几点&#xff1a; MSOCache文件夹的作用&#xff1a; MSOCache文件夹是Microsoft Office的本地安装源&#xff0c;用于存储Office安装和更新过程中所需的临时文件&#xff0c;如安装程序所需的组件、配置设置以及更新…...

数据网格和视图入门

WinForms数据网格&#xff08;GridControl类&#xff09;是一个数据感知控件&#xff0c;可以以各种格式&#xff08;视图&#xff09;显示数据。本主题包含以下部分&#xff0c;这些部分将指导您如何使用网格控件及其视图和列&#xff08;字段&#xff09;。 Grid Control’s…...

雨的轮回与生命的律动

雨的轮回与生命的律动 我们生活在一个充满变数的世界里&#xff0c;许多事情无法预测&#xff0c;如同这不知何时会停歇的雨。然而&#xff0c;尽管我们无法预知雨停的确切时刻&#xff0c;但我们深知&#xff0c;这场雨终将会过去&#xff0c;阳光终将再次洒满大地。这种对未…...

CANopen for Python 使用教程(二)

系列文章目录 前言 CANopen 标准的 Python 实现。该项目的目的是在一个简单的 Pythonic 接口中支持 CiA 301 标准中最常见的部分。它主要针对测试和自动化任务&#xff0c;而不是符合标准的主实施。 该库支持 Python 3.6 及以上版本。 一、特点 该库主要用作主库。 NMT 主站…...

React Native 导航系统实战(React Navigation)

导航系统实战&#xff08;React Navigation&#xff09; React Navigation 是 React Native 应用中最常用的导航库之一&#xff0c;它提供了多种导航模式&#xff0c;如堆栈导航&#xff08;Stack Navigator&#xff09;、标签导航&#xff08;Tab Navigator&#xff09;和抽屉…...

【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)

🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...

蓝桥杯3498 01串的熵

问题描述 对于一个长度为 23333333的 01 串, 如果其信息熵为 11625907.5798&#xff0c; 且 0 出现次数比 1 少, 那么这个 01 串中 0 出现了多少次? #include<iostream> #include<cmath> using namespace std;int n 23333333;int main() {//枚举 0 出现的次数//因…...

Unity | AmplifyShaderEditor插件基础(第七集:平面波动shader)

目录 一、&#x1f44b;&#x1f3fb;前言 二、&#x1f608;sinx波动的基本原理 三、&#x1f608;波动起来 1.sinx节点介绍 2.vertexPosition 3.集成Vector3 a.节点Append b.连起来 4.波动起来 a.波动的原理 b.时间节点 c.sinx的处理 四、&#x1f30a;波动优化…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)

船舶制造装配管理现状&#xff1a;装配工作依赖人工经验&#xff0c;装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书&#xff0c;但在实际执行中&#xff0c;工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...

Java求职者面试指南:计算机基础与源码原理深度解析

Java求职者面试指南&#xff1a;计算机基础与源码原理深度解析 第一轮提问&#xff1a;基础概念问题 1. 请解释什么是进程和线程的区别&#xff1f; 面试官&#xff1a;进程是程序的一次执行过程&#xff0c;是系统进行资源分配和调度的基本单位&#xff1b;而线程是进程中的…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

LRU 缓存机制详解与实现(Java版) + 力扣解决

&#x1f4cc; LRU 缓存机制详解与实现&#xff08;Java版&#xff09; 一、&#x1f4d6; 问题背景 在日常开发中&#xff0c;我们经常会使用 缓存&#xff08;Cache&#xff09; 来提升性能。但由于内存有限&#xff0c;缓存不可能无限增长&#xff0c;于是需要策略决定&am…...

计算机基础知识解析:从应用到架构的全面拆解

目录 前言 1、 计算机的应用领域&#xff1a;无处不在的数字助手 2、 计算机的进化史&#xff1a;从算盘到量子计算 3、计算机的分类&#xff1a;不止 “台式机和笔记本” 4、计算机的组件&#xff1a;硬件与软件的协同 4.1 硬件&#xff1a;五大核心部件 4.2 软件&#…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...