传统的解决思路:自定义一个拦截器,当有模糊查询时,模糊查询的关键字中包含有上述特殊字符时,在该特殊字符前添加\进行转义处理。

新的解决思路:将like 替换为 MySQL内置函数locate函数

参考博客:

    https://www.jianshu.com/p/f4d3e6ffeee8

    https://www.cnblogs.com/tommy-huang/p/4483583.html

  

一、问题提出

使用MyBatis中的模糊查询时,当查询关键字中包括有_\%时,查询关键字失效。

二、问题分析

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

特殊字符 未处理 处理后
_ like '%_%' like '%\_%'
% like '%%%' like '%\%%'
\ like '%\%' `like '%\%'
  • ESCAPE '/'必须加在SQL的最后。
  • like '%\_%'效果与like concat('%', '\_', '%')相同

三、问题解决

1、自定义拦截器方法类



import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.keyidea.boss.utils.EscapeUtil;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
import java.util.Set;

/**
 * 自定义拦截器方法,处理模糊查询中包含特殊字符(_、%、\)
 */
@Intercepts(@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
    RowBounds.class, ResultHandler.class}))
public class MyInterceptor implements Interceptor {

    Logger LOGGER = LoggerFactory.getLogger(MyInterceptor.class);

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 拦截sql
        Object[] args = invocation.getArgs();
        MappedStatement statement = (MappedStatement)args[0];
        Object parameterObject = args[1];
        BoundSql boundSql = statement.getBoundSql(parameterObject);
        String sql = boundSql.getSql();
        // 处理特殊字符
        modifyLikeSql(sql, parameterObject, boundSql);
        // 返回
        return invocation.proceed();
    }

    @Override
    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    @Override
    public void setProperties(Properties properties) {

    }

    @SuppressWarnings(

相关文章:

  • 2021-10-16
  • 2022-12-23
  • 2021-08-07
  • 2021-05-26
  • 2021-09-23
  • 2021-11-08
猜你喜欢
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 1970-01-01
  • 2021-08-07
  • 2022-12-23
相关资源
相似解决方案