MyBatis 特殊字符转义拦截器 针对(_、\、%)

2023-11-01

一、问题反馈

今天公司测试向我反馈,系统用户模糊查询功能在用户名称包含特殊字符时(_、\、%)无法正常查询结果。

二、问题验证

1、当like中包含_时,查询仍为全部,即 like '%_%'查询出来的结果与like '%%'一致,并不能查询出实际字段中包含有_特殊字符的结果条目
2、like中包括%时,与1中相同
3、like中包含\时,带入查询时,%\%无法查询到包含字段中有\的条目

三、问题解决思路

1、采用MyBatis 拦截器机制,处理模糊查询中包含特殊字符(_、\、%)

四、核心功能代码

4.1 MyBatis 特殊字符拦截器编写

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];
		// 请求参数对象
		Object parameterObject = args[1];

		// 获取 SQL
		SqlCommandType sqlCommandType = statement.getSqlCommandType();
		if (SqlCommandType.SELECT.equals(sqlCommandType)) {
			if (parameterObject instanceof HashMap) {
				// 调用特殊字符处理方法
				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("%", "\\\\%");
						// 请求参数对象HashMap重新赋值转义后的值
						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 通过@Configuration 标签,实例化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;
	}

	/**
	 * 分页对象实列化
	 * @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;
	}
}

效果展示:

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MyBatis 特殊字符转义拦截器 针对(_、\、%) 的相关文章

  • UE4_蓝图调试器

    蓝图调试器 在蓝图调式器里可以看到所有的断点和 watch this value 的值 下面这幅图可以取消所有的断点和watch this value 节点注释
  • opencv 直方图 CV::calcHist使用

    本文转自 http www xuebuyuan com 1014703 html 特别提醒读者 注意实例中数据成员很多都定义成数据 这是由于calcHist函数形参要求的 直方图在图形处理中很常用 直方图可以统计图像的像素特征分布 用于修改

随机推荐