当前位置: 首页 > 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 主站…...

django filter 统计数量 按属性去重

在Django中&#xff0c;如果你想要根据某个属性对查询集进行去重并统计数量&#xff0c;你可以使用values()方法配合annotate()方法来实现。这里有两种常见的方法来完成这个需求&#xff1a; 方法1&#xff1a;使用annotate()和Count 假设你有一个模型Item&#xff0c;并且你想…...

定时器任务——若依源码分析

分析util包下面的工具类schedule utils&#xff1a; ScheduleUtils 是若依中用于与 Quartz 框架交互的工具类&#xff0c;封装了定时任务的 创建、更新、暂停、删除等核心逻辑。 createScheduleJob createScheduleJob 用于将任务注册到 Quartz&#xff0c;先构建任务的 JobD…...

【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力

引言&#xff1a; 在人工智能快速发展的浪潮中&#xff0c;快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型&#xff08;LLM&#xff09;。该模型代表着该领域的重大突破&#xff0c;通过独特方式融合思考与非思考…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

【决胜公务员考试】求职OMG——见面课测验1

2025最新版&#xff01;&#xff01;&#xff01;6.8截至答题&#xff0c;大家注意呀&#xff01; 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:&#xff08; B &#xff09; A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题

在数字化浪潮席卷全球的今天&#xff0c;软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件&#xff0c;这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下&#xff0c;实现高效测试与快速迭代&#xff1f;这一命题正考验着…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)

名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...

windows系统MySQL安装文档

概览&#xff1a;本文讨论了MySQL的安装、使用过程中涉及的解压、配置、初始化、注册服务、启动、修改密码、登录、退出以及卸载等相关内容&#xff0c;为学习者提供全面的操作指导。关键要点包括&#xff1a; 解压 &#xff1a;下载完成后解压压缩包&#xff0c;得到MySQL 8.…...

Kafka主题运维全指南:从基础配置到故障处理

#作者&#xff1a;张桐瑞 文章目录 主题日常管理1. 修改主题分区。2. 修改主题级别参数。3. 变更副本数。4. 修改主题限速。5.主题分区迁移。6. 常见主题错误处理常见错误1&#xff1a;主题删除失败。常见错误2&#xff1a;__consumer_offsets占用太多的磁盘。 主题日常管理 …...