mybatis-plus like 查询 转义特殊字符%_\

场景:
like CONCAT(’%’,?,’%’) 查询的参数 中 包含 特殊字符 %\ 导致结果查询结果不是期望值,被like查询字段值内容包含 %\ 字符。

mybaits-plus 拦截器解决


import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.sql.SQLException;
import java.util.HashSet;
import java.util.Set;

/**
 * 特殊字符转换 like 查询
 * 

* 参数中的特殊查询字符 _ % \ *

* 注意事项 : * 1. 必须是在 分页拦截器之前执行 [注意拦截器的顺序] * */ public class SpecialCharacterConversionLikeInnerInterceptor implements InnerInterceptor { @Override public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException { String sql = boundSql.getSql().toLowerCase(); // 判断是否包含 参数 及 like 查询 if (!sql.contains(" like ") || !sql.contains("?")) { return; } // 获取关键字的个数(去重),获取 到 like 查询 的 key String[] strList = sql.split("\\?"); Set<String> keyNames = new HashSet<>(); for (int i = 0; i < strList.length; i++) { if (strList[i].toLowerCase().contains(" like ")) { String keyName = boundSql.getParameterMappings().get(i).getProperty(); keyNames.add(keyName); } } MetaObject metaObject = ms.getConfiguration().newMetaObject(parameter); for (String keyName : keyNames) { Object value = metaObject.getValue(keyName); if (value instanceof String) { if (isconvert((String) value)) { metaObject.setValue(keyName, convert((String) value)); } } } } private String convert(String before) { if (StringUtils.isNotBlank(before)) { before = before.replaceAll("\\\\", "\\\\\\\\"); before = before.replaceAll("_", "\\\\_"); before = before.replaceAll("%", "\\\\%"); } return before; } private boolean isconvert(String str) { return str.contains("\\") || str.contains("_") || str.contains("%"); } }

注意拦截器的顺序,注入到spring 容器中

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        //	自定义 的 like 转义特殊字符%_\
        interceptor.addInnerInterceptor(new SpecialCharacterConversionLikeInnerInterceptor());
        //	mybatis-plus 的 分页查询
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
        return interceptor;
    }

你可能感兴趣的:(mybatis-plus,mybatis)