开发者

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

目录
  • 一、问题反馈
  • 二、问题验证
  • 三、问题解决思路
  • 四、核心功能代码
    • 4.1 MyBATis 特殊字符拦截器编写
    • 4.2 通过@Configuration标签
  • 总结

    一、问题反馈

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

    二、问题验证

    1、当like中包含_时,查询仍为全部,即 like '%_%'查询出来的结果与like '%%'一致,并不能查询出实际字段中包含有_特殊字符的结果条目

    2、like中包括%时,与1中相同

    3、like中包含\时,带入查询时,%\%无法查询到包含字段中有\的条目

    三、问题解决思路

    采用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.Invophpcation;
    import org.apache.ibatis.plugin.Plugin;
    import org.apache.ibatis.plugin.Signature;
    import org.apache.ibatis.session.ResultHandler;
    import org.apache.ibatis.session.RowBounds;
     
    /**
     * 自定义拦截器方法,处理模糊查询中包含特殊字符(_、%、\)
     */
    @In编程客栈tercepts({
    		@Signature(type = Executor.class, method = "query", args = { MappedStatement.class, Object.class,
    				RowBounds.class, ResultHandler.class }),
    		@Signature(type = Executor.cla开发者_Python培训ss, 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.intjserceptor.EscapeInterceptor;
    import com.github.pagehelper.PageHelper;
     
    @Configuration
    public class MyBatisConfig {
    	
    	/**
    	 * mybatis 自定义拦截器(特殊字符处理)
    	 * @return
    	 */
    	@Bean
    	public EscapeInterceptor getEscapeInterceptor(){
    		EscapeInterceptor interceptor = new EscapeInterceptor();
    		return interceptor;
    	}
     
    js	/**
    	 * 分页对象实列化
    	 * @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.setjavascriptProperty("dialect", "mysql");
    		pageHelper.setProperties(p);
    		return pageHelper;
    	}
    }

    效果展示:

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

    总结

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。

    0

    上一篇:

    下一篇:

    精彩评论

    暂无评论...
    验证码 换一张
    取 消

    最新开发

    开发排行榜