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 >= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date <= #{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 >= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date <= #{endDate} </if></where></select>
原因分析:
- 首先,确定前端的字段是否完整的传递到Controller,通过Console.log(参数)的方式将参数打印在浏览器控制台中,经过验证参数传递无异常;
- 其次,在Controller及Service中获取参数并打印,确保参数传递过程没有缺失等;
- 查看查询日志:
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}’%。
解决方案:
- 通过在#{name}前后添加空格,让MyBatis正确的识别并拼接参数与字符串;
- 更严谨的方式是使用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 >= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date <= #{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 >= #{startDate}</if><if test="endDate != null and endDate != ''"> and a.end_date <= #{endDate} </if></where></select>
相关文章:
MyBatis进行模糊查询时SQL语句拼接引起的异常问题
项目场景: CRM项目,本文遇到的问题是在实现根据页面表单中输入条件,在数据库中分页模糊查询数据,并在页面分页显示的功能时,出现的“诡异”bug。 开发环境如下: 操作系统:Windows11 Java&#…...
网站调用Edge浏览器API:https://api-edge.cognitive.microsofttranslator.com/translate
Edge浏览器有自带的翻译功能,在运行pc项目可能会遇到疯狂调用Edge的API https://api-edge.cognitive.microsofttranslator.com/translate 这个URL(https://api-edge.cognitive.microsofttranslator.com/translate)指向的是微软服务中的API接…...
css实现优惠券样式
实现优惠券效果: 实现思路: 需要三个盒子元素,使用 css 剪裁,利用 ellipse 属性,将两个盒子分别裁剪成两个半圆,位置固定在另一个盒子元素左右两边适当位置上。为另一个盒子设置想要的样式,圆角…...
函数递归(C语言)(详细过程!)
函数递归 一. 递归是什么1.1 递归的思想1.2 递归的限制条件 二. 递归举例2.1 求n的阶乘2.2 按顺序打印一个整数的每一位 三. 递归与迭代3.1 求第n个斐波那契数 一. 递归是什么 递归是学习C语言很重要的一个知识,递归就是函数自己调用自己,是一种解决问题…...
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++中的观察者模式
目录 观察者模式(Observer Pattern) 实际应用 股票价格监控系统 发布-订阅系统 总结 观察者模式(Observer Pattern) 观察者模式是一种行为型设计模式,它定义了对象间的一对多依赖关系。当一个对象的状态发生改变…...
conda虚拟环境,安装pytorch cuda cudnn版本一致,最简单方式
1、pytorch版本安装(卸载也会有问题) (1)版本如何选择参考和卸载 https://zhuanlan.zhihu.com/p/401931724 (2)对应版本如何安装命令 https://pytorch.org/get-started/previous-versions/ 最简答安装参考…...
第 5 章:面向生产的 Spring Boot
在 4.1.2 节中,我们介绍了 Spring Boot 的四大核心组成部分,第 4 章主要介绍了其中的起步依赖与自动配置,本章将重点介绍 Spring Boot Actuator,包括如何通过 Actuator 提供的各种端点(endpoint)了解系统的…...
在 Windows 操作系统中,可以通过命令行工具来杀死进程
1. 使用 taskkill 命令 taskkill 命令是一个用于终止进程的命令行工具,可以通过进程名称或进程 ID (PID) 来杀死进程。 按进程名称杀死进程 taskkill /IM processname.exe /Fprocessname.exe 是进程的名称。/F 参数表示强制终止进程。 例如,终止名为…...
uni-app文件下载 h5 xls 乱码 锟斤拷 Blob pdf打不开
原先下载方式,PC管理端和浏览器打开文件能下载,xls没出现乱码,pdf能正常显示,H5下载xls乱码锟斤拷,PDF显示空白内容 怀疑是前端问题,也尝试过修改后端代码 后端设置编码格式 response.setCharacterEncoding(characte…...
Vue25-内置指令02:v-text指令
一、v-html对比v-text v-html支持结构的解析,v-text不支持结构的解析。 二、v-html的安全性问题 2-1、cookie的原理(node.js) 7天免登录,cookie实现。 cookie的本质就是类似于json的字符串,格式是: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板打样焊接图 五、程序设计 六、实验效果 七、资料内容 项目分享 一、前言 项目成品图片: 哔哩哔哩视频链接: https://www.bilibili.c…...
PDU模块中浪涌保护模块与空开模块的应用
由于PDU具体应用的特殊性,其在规划设计时具有应用场景的针对性,同时PDU的高度定制化的特点,是其他电气联接与保护产品所不具备的。 PDU基础的输出输入功能外,其电路的控制与电压保护器同时也极为重要。空气开关和浪涌保护器相关功…...
19、Go Gin框架集成Swagger
介绍: Swagger 支持在 Gin 路由中使用一系列注释来描述 API 的各个方面。以下是一些常用的 Swagger 注释属性,这些属性可以在 Gin 路由的注释中使用: Summary: 路由的简短摘要。Description: 路由的详细描述。Tags: 用于对路由进行分类的标…...
自动同步库数据——kettle开发36
kettle中的那些人工智能。 一、kettle的AI能力目录 跨库同步 2.自动开发 3.自动优化 二、AI实例 1、跨库同步 sqlsever表同步至oracle数据库 1.1源库sqlserver 1.2目标库oracle 1.3可视化跨库同步 使用多表复制向导 选择跨库的表,下一步下一步,即可…...
MSOCache在电脑中可以删除吗?
MSOCache文件夹在电脑中是可以删除的。但删除前需要了解以下几点: MSOCache文件夹的作用: MSOCache文件夹是Microsoft Office的本地安装源,用于存储Office安装和更新过程中所需的临时文件,如安装程序所需的组件、配置设置以及更新…...
数据网格和视图入门
WinForms数据网格(GridControl类)是一个数据感知控件,可以以各种格式(视图)显示数据。本主题包含以下部分,这些部分将指导您如何使用网格控件及其视图和列(字段)。 Grid Control’s…...
雨的轮回与生命的律动
雨的轮回与生命的律动 我们生活在一个充满变数的世界里,许多事情无法预测,如同这不知何时会停歇的雨。然而,尽管我们无法预知雨停的确切时刻,但我们深知,这场雨终将会过去,阳光终将再次洒满大地。这种对未…...
CANopen for Python 使用教程(二)
系列文章目录 前言 CANopen 标准的 Python 实现。该项目的目的是在一个简单的 Pythonic 接口中支持 CiA 301 标准中最常见的部分。它主要针对测试和自动化任务,而不是符合标准的主实施。 该库支持 Python 3.6 及以上版本。 一、特点 该库主要用作主库。 NMT 主站…...
Prompt Tuning、P-Tuning、Prefix Tuning的区别
一、Prompt Tuning、P-Tuning、Prefix Tuning的区别 1. Prompt Tuning(提示调优) 核心思想:固定预训练模型参数,仅学习额外的连续提示向量(通常是嵌入层的一部分)。实现方式:在输入文本前添加可训练的连续向量(软提示),模型只更新这些提示参数。优势:参数量少(仅提…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
免费PDF转图片工具
免费PDF转图片工具 一款简单易用的PDF转图片工具,可以将PDF文件快速转换为高质量PNG图片。无需安装复杂的软件,也不需要在线上传文件,保护您的隐私。 工具截图 主要特点 🚀 快速转换:本地转换,无需等待上…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
ZYNQ学习记录FPGA(一)ZYNQ简介
一、知识准备 1.一些术语,缩写和概念: 1)ZYNQ全称:ZYNQ7000 All Pgrammable SoC 2)SoC:system on chips(片上系统),对比集成电路的SoB(system on board) 3)ARM:处理器…...
篇章二 论坛系统——系统设计
目录 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 1. 数据库设计 1.1 数据库名: forum db 1.2 表的设计 1.3 编写SQL 2.系统设计 2.1 技术选型 2.2 设计数据库结构 2.2.1 数据库实体 通过需求分析获得概念类并结合业务实现过程中的技术需要&#x…...
Vue 3 + WebSocket 实战:公司通知实时推送功能详解
📢 Vue 3 WebSocket 实战:公司通知实时推送功能详解 📌 收藏 点赞 关注,项目中要用到推送功能时就不怕找不到了! 实时通知是企业系统中常见的功能,比如:管理员发布通知后,所有用户…...
文件上传漏洞防御全攻略
要全面防范文件上传漏洞,需构建多层防御体系,结合技术验证、存储隔离与权限控制: 🔒 一、基础防护层 前端校验(仅辅助) 通过JavaScript限制文件后缀名(白名单)和大小,提…...
深入解析光敏传感技术:嵌入式仿真平台如何重塑电子工程教学
一、光敏传感技术的物理本质与系统级实现挑战 光敏电阻作为经典的光电传感器件,其工作原理根植于半导体材料的光电导效应。当入射光子能量超过材料带隙宽度时,价带电子受激发跃迁至导带,形成电子-空穴对,导致材料电导率显著提升。…...
