Mybatis中LIKE特殊字符处理的解决方案

在MySQL使用LIKE进行模糊匹配时,特殊字符需要转义。Mybatis和Mybatis-Plus未提供自动转义,可通过实现插件接口或使用切面结合注解的方式解决。方案一利用mybatis插件接口拦截,但对某些查询方式有局限性;方案二通过AOP和自定义注解,灵活性更高且无歧义问题,适用于特定接口处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在MYSQL中,使用LIKE关键字进行模糊匹配时候,特殊字符是需要转义的,如下: \ 转义成 \\ , _ 转义成 \_ , % 转义成 \%
在mybatis和mybatis-plus中,没有提供相关的方法来自动转义。其实这是符合逻辑的,转义这种事情该交给开发者自己去处理,官方框架不去入侵这种逻辑代码也是为了更好的灵活性。
在业务开发的环境中,往往会有测试提出这样的bug:“输入特殊字符进行筛选,没有过滤掉对应的数据”。像这种问题其实本质上是不应该存在的,在根源上就应该切除掉,就是说禁止输入特殊字符进行筛选。但往往测试和产品他们根本不懂技术,你也别废口舌去和他们争论了。那么我们就来看看如何处理关于LIKE特殊字符转义问题。

方案一:实现mybatis的插件接口

我们知道mybatis提供了插件接口方便开发者进行二次开发。mybatis-plus对mybatis进行了增强,在mybatis-plus中需要实现InnerInterceptor接口进行拦截。如果只是引入的mybatis,则实现Interceptor接口进行拦截。注意一下:
该方案对 like xxx%like %xxx 的查询方式会有一定的局限性。如:
用户输入 = %a 时,业务按照 like xxx% 的语义查询,是查询xxx开头的数据。正常该转义成 like \%a%
用户输入 = a% 时,业务按照 like %xxx 的语义查询,是查询xxx结尾的数据。正常该转义成 like %a\%
但程序在转换时,依然会按照 like %xxx% 的语义去转义。这是不可避免的,因为这确实是歧义的地方。 程序解析 like %a% 时,无法完全地确定哪一部分是用户输入的,所以只有按照标准的 %xxx% 来进行解析转义。
不过在一般的业务查询中,左LIKE 和 右LIKE 很少用到,可以不用考虑此情况。
下面是实现了mybatis-plus的拦截接口,代码如下:

import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import lombok.extern.slf4j.Slf4j;
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.reflection.SystemMetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

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

/**
 * @author shaohuailin
 * @date 2023/10/8
 */
@Slf4j
public class LikeEscapeInnerInterceptor implements InnerInterceptor {
   

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
   
        escapeLike(boundSql);
    }

    /**
     * like条件中若有关键字,则进行转义
     *
     * @param boundSql
     */
    public 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值