MyBatis特殊字符轉(zhuǎn)義攔截器問(wèn)題針對(duì)(_、\、%)
一、問(wèn)題反饋
今天公司測(cè)試向我反饋,系統(tǒng)用戶模糊查詢功能在用戶名稱包含特殊字符時(shí)(_、\、%)無(wú)法正常查詢結(jié)果。
二、問(wèn)題驗(yàn)證
1、當(dāng)like中包含_時(shí),查詢?nèi)詾槿?,?like '%_%'查詢出來(lái)的結(jié)果與like '%%'一致,并不能查詢出實(shí)際字段中包含有_特殊字符的結(jié)果條目
2、like中包括%時(shí),與1中相同
3、like中包含\時(shí),帶入查詢時(shí),%\%無(wú)法查詢到包含字段中有\的條目
三、問(wèn)題解決思路
采用MyBatis 攔截器機(jī)制,處理模糊查詢中包含特殊字符(_、\、%)
四、核心功能代碼
4.1 MyBatis 特殊字符攔截器編寫(xiě)
package com.zzg.sql.interceptor;
import java.util.HashMap;
import java.util.Properties;
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.SqlCommandType;
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.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
/**
* 自定義攔截器方法,處理模糊查詢中包含特殊字符(_、%、\)
*/
@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 EscapeInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
// TODO Auto-generated method stub
// 攔截sql
Object[] args = invocation.getArgs();
MappedStatement statement = (MappedStatement) args[0];
// 請(qǐng)求參數(shù)對(duì)象
Object parameterObject = args[1];
// 獲取 SQL
SqlCommandType sqlCommandType = statement.getSqlCommandType();
if (SqlCommandType.SELECT.equals(sqlCommandType)) {
if (parameterObject instanceof HashMap) {
// 調(diào)用特殊字符處理方法
HashMap hash = (HashMap) parameterObject;
hash.forEach((k, v) -> {
// 僅攔截字符串類型且值不為空
if (v != null && v instanceof String) {
String value = (String) v;
value = value.replaceAll("\\\\", "\\\\\\\\");
value = value.replaceAll("_", "\\\\_");
value = value.replaceAll("%", "\\\\%");
// 請(qǐng)求參數(shù)對(duì)象HashMap重新賦值轉(zhuǎn)義后的值
hash.put(k, value);
}
});
}
}
// 返回
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
// TODO Auto-generated method stub
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
// TODO Auto-generated method stub
}
}4.2 通過(guò)@Configuration標(biāo)簽
實(shí)例化EscapeInterceptor 攔截器。
package com.zzg.config;
import java.util.Properties;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.zzg.sql.interceptor.EscapeInterceptor;
import com.github.pagehelper.PageHelper;
@Configuration
public class MyBatisConfig {
/**
* mybatis 自定義攔截器(特殊字符處理)
* @return
*/
@Bean
public EscapeInterceptor getEscapeInterceptor(){
EscapeInterceptor interceptor = new EscapeInterceptor();
return interceptor;
}
/**
* 分頁(yè)對(duì)象實(shí)列化
* @return
*/
@Bean
public PageHelper pageHelper() {
PageHelper pageHelper = new PageHelper();
Properties p = new Properties();
p.setProperty("offsetAsPageNum", "true");
p.setProperty("rowBoundsWithCount", "true");
p.setProperty("reasonable", "true");
p.setProperty("dialect", "mysql");
pageHelper.setProperties(p);
return pageHelper;
}
}效果展示:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot org.springframework.beans.factory.Unsatisfie
本文主要介紹了SpringBoot org.springframework.beans.factory.UnsatisfiedDependencyException依賴注入異常,文中通過(guò)示例代碼介紹的很詳細(xì),具有一定的參考價(jià)值,感興趣的可以了解一下2024-02-02
基于mybatis-plus timestamp返回為null問(wèn)題的排除
這篇文章主要介紹了mybatis-plus timestamp返回為null問(wèn)題的排除,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-08-08
Springboot @Value注入boolean設(shè)置默認(rèn)值方式
這篇文章主要介紹了Springboot @Value注入boolean設(shè)置默認(rèn)值方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03
intellij idea隱藏.iml和.idea等自動(dòng)生成文件的問(wèn)題
這篇文章主要介紹了intellij idea隱藏.iml和.idea等自動(dòng)生成文件的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Spring Cloud Gateway全局通用異常處理的實(shí)現(xiàn)
這篇文章主要介紹了Spring Cloud Gateway全局通用異常處理的實(shí)現(xiàn),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05
Spring自定義注解實(shí)現(xiàn)接口版本管理
這篇文章主要介紹了Spring自定義注解實(shí)現(xiàn)接口版本管理,RequestMappingHandlerMapping類是與 @RequestMapping相關(guān)的,它定義映射的規(guī)則,即滿足怎樣的條件則映射到那個(gè)接口上,需要的朋友可以參考下2023-11-11
java對(duì)象數(shù)組實(shí)現(xiàn)學(xué)生信息管理系統(tǒng)
這篇文章主要為大家詳細(xì)介紹了java對(duì)象數(shù)組實(shí)現(xiàn)學(xué)生信息管理系統(tǒng),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-06-06
log4j2 RollingRandomAccessFile配置過(guò)程
這篇文章主要介紹了log4j2 RollingRandomAccessFile配置過(guò)程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-07-07
Spring?Boot+RabbitMQ?通過(guò)fanout模式實(shí)現(xiàn)消息接收功能(支持消費(fèi)者多實(shí)例部署)
這篇文章主要介紹了Spring?Boot+RabbitMQ?通過(guò)fanout模式實(shí)現(xiàn)消息接收(支持消費(fèi)者多實(shí)例部署),本文通過(guò)案例場(chǎng)景分析給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-03-03
解決SpringBoot中使用@Transactional注解遇到的問(wèn)題
這篇文章主要介紹了SpringBoot中使用@Transactional注解遇到的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09

