搜索模糊匹配% _ 等特殊字符转义工具

mysql 和达梦数据库不同的解决方式:
mysql 数据库 解决搜索框传入%等特殊字符查询全部数据的问题:

/***@author liuxingying*@description 搜索转义工具类*@since 2023/11/30*/
public class EscapeUtil {/*** sql的模糊查询时特殊字符转义(条件查询%或者_查询所有问题)*/public static String escapeChar(String str){if(StringUtils.isNotBlank(str)){if (str.contains("/")){str = str.replaceAll("/", "\\\\/");}if (str.contains("%")){str = str.replaceAll("%", "\\\\%");}if (str.contains("_")){str = str.replaceAll("_", "\\\\_");}}return str.trim();}
}

达梦 数据库 解决搜索框传入%等特殊字符查询全部数据的问题:
加入mybatis拦截器处理

package com.dx.radar.data;import org.apache.ibatis.cache.CacheKey;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Component;import java.lang.reflect.Field;
import java.util.List;
import java.util.Properties;
import java.util.regex.Matcher;
import java.util.regex.Pattern;/*** @author liuxingying* @since 2024/3/28*/
@Component
@Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}),@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),}
)
public class MybatisEscapeInterceptor implements Interceptor {static final String REG_EXP_LIKE_CONTAIN = "^.*(like\\s*\\?|like\\s*concat\\s*[(]\\s*'%'\\s*,\\s*concat\\s*[(]\\s*\\?\\s*,\\s*'%'\\s*[)]\\s*[)]).*$";static final String REG_EXP_PROCESSED_PARAM = "^.*(\\\\%|\\\\_).*$";static final String REG_EXP_UNPROCESSED_PARAM = "^.*(%|_).*$";@Overridepublic Object intercept(Invocation invocation) throws Throwable {Object[] args = invocation.getArgs();MappedStatement mappedStatement = (MappedStatement) args[0];Object parameter = args[1];RowBounds rowBounds = (RowBounds) args[2];ResultHandler resultHandler = (ResultHandler) args[3];Executor executor = (Executor) invocation.getTarget();CacheKey cacheKey;BoundSql boundSql;if (args.length == 4) {boundSql = mappedStatement.getBoundSql(parameter);cacheKey = executor.createCacheKey(mappedStatement, parameter, rowBounds, boundSql);} else {cacheKey = (CacheKey) args[4];boundSql = (BoundSql) args[5];}String sql = boundSql.getSql();String newSql = modifyLikeSql(sql, parameter, boundSql, mappedStatement);Field field = boundSql.getClass().getDeclaredField("sql");field.setAccessible(true);field.set(boundSql, newSql);return executor.query(mappedStatement, parameter, rowBounds, resultHandler, cacheKey, boundSql);}@Overridepublic Object plugin(Object target) {return Plugin.wrap(target, this);}@Overridepublic void setProperties(Properties properties) {}public static String modifyLikeSql(String sql, Object parameterObject, BoundSql boundSql, MappedStatement mappedStatement) {if (!matches(REG_EXP_LIKE_CONTAIN, sql) || sql.contains(" ESCAPE '\\\\' ")) {return sql;}List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();if (parameterMappings != null) {int j = 0;Matcher matcher = getMatcher("\\?", sql);StringBuffer sb = new StringBuffer();while (matcher.find()) {matcher.appendReplacement(sb, "#{" + j + "}");j++;}matcher.appendTail(sb);sql = sb.toString();for (int i = 0; i < parameterMappings.size(); i++) {ParameterMapping parameterMapping = parameterMappings.get(i);if (parameterMapping.getMode() != ParameterMode.OUT) {Object value;String propertyName = parameterMapping.getProperty();if (boundSql.hasAdditionalParameter(propertyName)) {value = boundSql.getAdditionalParameter(propertyName);if (value instanceof String) {String val = (String) value;if (val.equals("%%")) {continue;}if (!matches(REG_EXP_PROCESSED_PARAM, val) && matches(REG_EXP_UNPROCESSED_PARAM, val) && matches(getRegExpLikeContain(i), sql)) {val = resetParam(val);boundSql.setAdditionalParameter(propertyName, val);value = val;}}} else if (parameterObject == null) {value = null;} else if (mappedStatement.getConfiguration().getTypeHandlerRegistry().hasTypeHandler(parameterObject.getClass())) {value = parameterObject;} else {MetaObject metaObject = mappedStatement.getConfiguration().newMetaObject(parameterObject);value = metaObject.getValue(propertyName);if (value instanceof String) {String val = (String) value;if (val.equals("%%")) {continue;}if (!matches(REG_EXP_PROCESSED_PARAM, val) && matches(REG_EXP_UNPROCESSED_PARAM, val) && matches(getRegExpLikeContain(i), sql)) {val = resetParam(val);metaObject.setValue(propertyName, val);value = val;}}}if (value instanceof String) {if (matches(REG_EXP_PROCESSED_PARAM, ((String) value))) {sql = matchesReplace(getRegExpLike(i), sql, " LIKE ? ESCAPE '\\\\' ");}}}}}sql = matchesReplace("#\\{\\d+\\}", sql, " ? ");return sql;}private static String resetParam(String val) {if (!"%".equals(val) && !"%%".equals(val) && !"_".equals(val) && !"__".equals(val)) {if (val.startsWith("%") || val.startsWith("_")) {val = val.substring(1);}if (val.endsWith("%") || val.endsWith("_")) {val = val.substring(0, val.length() - 1);}}val = val.replaceAll("%", "\\\\%");val = val.replaceAll("_", "\\\\_");val = "%" + val + "%";return val;}private static String getRegExpLike(int i) {return "like\\s*#\\{" + i + "\\}|like\\s*concat\\s*[(]\\s*'%'\\s*,\\s*concat\\s*[(]\\s*#\\{" + i + "\\}\\s*,\\s*'%'\\s*[)]\\s*[)]";}private static String getRegExpLikeContain(int i) {return "^.*(like\\s*#\\{" + i + "\\}|like\\s*concat\\s*[(]\\s*'%'\\s*,\\s*concat\\s*[(]\\s*#\\{" + i + "\\}\\s*,\\s*'%'\\s*[)]\\s*[)]).*$";}private static String matchesReplace(String regExp, String input, String replaceStr) {Matcher matcher = getMatcher(regExp, input);StringBuffer sb = new StringBuffer();while (matcher.find()) {matcher.appendReplacement(sb, replaceStr);}matcher.appendTail(sb);return sb.toString();}private static boolean matches(String regExp, String input) {return getMatcher(regExp, input).matches();}private static Matcher getMatcher(String regExp, String input) {Pattern pattern = Pattern.compile(regExp, Pattern.CASE_INSENSITIVE | Pattern.DOTALL);return pattern.matcher(input);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/779556.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Intel Arc显卡安装Stable Diffusion

StableDiffusion是一种基于深度学习的文本到图像生成模型&#xff0c;于2022年发布。它主要用于根据文本描述生成详细图像&#xff0c;也可应用于其他任务&#xff0c;如内补绘制、外补绘制和在提示词指导下生成图像翻译。通过给定文本提示词&#xff0c;该模型会输出一张匹配提…

gitee多用户配置

一、引言 在工作的时候我们有时候会自己创建项目Demo来实现一些功能&#xff0c;但是又不想把自己的Demo代码放到公司的仓库代码平台&#xff08;gitee&#xff09;中管理&#xff0c;于是就是想自己放到自己的Gitee中管理&#xff0c;于是就需要配置Git多用户。 本文将配置分别…

javascript解决接口请求过慢新的接口返回数据被旧的接口覆盖问题

今天请求接口的时候发现最新一次接口数据被上一次接口请求数据覆盖&#xff0c;原因是上一次接口用了2~3s,本次接口请求用了10ms, 导致新的数据被旧数据覆盖, 为了避免上一次请求的代码执行在本次请求之后才响应结束&#xff0c;使用Promise来管理异步操作。在每次请求开始时创…

串行流(Sequential Stream)和并行流(Parallel Stream)区别

在 Java 中&#xff0c;串行流和并行流是针对流操作的两种不同处理方式&#xff1a; 串行流&#xff08;Sequential Stream&#xff09;&#xff1a; 串行流是流元素按顺序依次处理的流。在串行流中&#xff0c;操作是单线程执行的&#xff0c;每个元素依次经过流水线上的各个…

力扣46---全排列(递归)

给定一个不含重复数字的数组 nums &#xff0c;返回其 所有可能的全排列 。你可以 按任意顺序 返回答案。 示例 1&#xff1a; 输入&#xff1a;nums [1,2,3] 输出&#xff1a;[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]示例 2&#xff1a; 输入&#xff1a;nums …

vue2之各种插槽

插槽也是用于vue间创建的数据的一种方式&#xff0c;一般都是传递html元素。比如可以用于定义一个带样式的title等 默认插槽&#xff1a;没有name的插槽 ----父组件------ <template><div><TypeCom><!-- 如果这里的注释放开&#xff0c;那么子组件中默认…

【Go】五、流程控制

文章目录 1、if2、switch3、for4、for range5、break6、continue7、goto8、return 1、if 条件表达式左右的()是建议省略的if后面一定要有空格&#xff0c;和条件表达式分隔开来{ }一定不能省略if后面可以并列的加入变量的定义 if count : 20;count < 30 {fmt.Println(&quo…

基于springboot实现课程作业管理系统项目【项目源码+论文说明】

基于springboot实现课程作业管理系统演示 摘要 随着科学技术的飞速发展&#xff0c;社会的方方面面、各行各业都在努力与现代的先进技术接轨&#xff0c;通过科技手段来提高自身的优势&#xff0c;课程作业管理系统当然也不能排除在外。课程作业管理系统是以实际运用为开发背景…

Transformers —— 以通俗易懂的方式解释-Part 1

公众号:Halo咯咯,欢迎关注~ 本系列主要介绍了为ChatGPT以及许多其他大型语言模型(LLM)提供支持的Transformer神经网络。我们将从基础的Transformer概念开始介绍,尽量避免使用数学和技术细节,使得更多人能够理解这一强大的技术。 Transformers —— 以通俗易懂的方式解释…

数据结构——lesson11排序之快速排序

&#x1f49e;&#x1f49e; 前言 hello hello~ &#xff0c;这里是大耳朵土土垚~&#x1f496;&#x1f496; &#xff0c;欢迎大家点赞&#x1f973;&#x1f973;关注&#x1f4a5;&#x1f4a5;收藏&#x1f339;&#x1f339;&#x1f339; &#x1f4a5;个人主页&#x…

缓存雪崩问题及解决思路

实战篇Redis 2.7 缓存雪崩问题及解决思路 缓存雪崩是指在同一时段大量的缓存key同时失效或者Redis服务宕机&#xff0c;导致大量请求到达数据库&#xff0c;带来巨大压力。 解决方案&#xff1a; 给不同的Key的TTL添加随机值利用Redis集群提高服务的可用性给缓存业务添加降…

如何制作透明文件夹?

哇&#xff01;是不是很羡慕&#xff1f; 保姆级教程来啦&#xff01; 我们先新建一个文件夹 这么辛苦写文章&#xff0c;可以给我点个关注么~

好用的AI智能便签是哪款?桌面便签哪款比较智能

随着科技的日新月异&#xff0c;我们的生活与工作中涌现出众多便捷的软件工具&#xff0c;它们不仅提升了我们的生活质量&#xff0c;更在工作效率上给予了极大的助力。其中&#xff0c;便签软件以其简单实用的特性&#xff0c;成为了许多人日常不可或缺的好帮手。而在众多便签…

vue 计算属性

基础示例​ 模板中的表达式虽然方便&#xff0c;但也只能用来做简单的操作。如果在模板中写太多逻辑&#xff0c;会让模板变得臃肿&#xff0c;难以维护。比如说&#xff0c;我们有这样一个包含嵌套数组的对象&#xff1a; const author reactive({name: John Doe,books: [V…

量化交易入门(二十八)什么是布林带,量化中怎么使用

什么叫布林带 布林带&#xff08;Bollinger Bands&#xff09;是一种常用的技术分析指标&#xff0c;由约翰布林&#xff08;John Bollinger&#xff09;于20世纪80年代开发。它由三条线组成&#xff1a;中轨&#xff08;通常为20日移动平均线&#xff09;、上轨&#xff08;中…

【IC前端虚拟项目】write_path子模块DS与RTL编码

【IC前端虚拟项目】数据搬运指令处理模块前端实现虚拟项目说明-CSDN博客 read_path的代码完成之后,就可以开始整个项目里复杂度最高、bug最多、时序收敛最为困难的模块——write_path的开发了!我自己写过两次这个虚拟项目,每次都是在这里耗时最久,所以大家也可以挑战一下自…

Java虚拟机(JVM)知识点总结

一. Java内存区域 1. JVM的内存区域划分&#xff0c;以及各部分的作用 可分为运行时数据区域和本地内存&#xff0c;按照线程私有和线程共享分类&#xff1a; 线程私有&#xff1a;程序计数器、虚拟机栈、本地方法栈。 线程共享&#xff1a;堆、方法区、直接内存。 JDK1.7…

[Python GUI PyQt] PyQt5快速入门

PyQt5快速入门 PyQt5的快速入门0. 写在前面1. 思维导图2. 第一个PyQt5的应用程序3. PyQt5的常用基本控件和布局3.1 PyQt5的常用基本控件3.1.1 按钮控件 QPushButton3.1.2 文本标签控件 QLabel3.1.3 单行输入框控件 QLineEdit3.1.4 A Quick Widgets Demo 3.2 PyQt5的常用基本控件…

斜坡发生器(也称为斜坡函数或斜坡控制)是一种用于渐进式地改变系统中某个参数或状态的算法

斜坡发生器&#xff08;也称为斜坡函数或斜坡控制&#xff09;是一种用于渐进式地改变系统中某个参数或状态的算法。在自动化控制系统&#xff08;如机器人控制、电机控制、过程控制等&#xff09;中&#xff0c;当参数需要从一个值平滑地过渡到另一个值&#xff0c;而不是瞬间…

Redis入门到实战-第五弹

Redis入门到实战 Redis中Hashes数据类型常见操作官网地址Redis概述Hashes常见操作更新计划 Redis中Hashes数据类型常见操作 完整命令参考官网 官网地址 声明: 由于操作系统, 版本更新等原因, 文章所列内容不一定100%复现, 还要以官方信息为准 https://redis.io/Redis概述 R…