postgresql和kingbase关于模糊查询大小写兼容问题

在mysql中,会有相关的like关键词,并且默认的是忽略大小写的。但是在postgresql和kingbase中,只有ilike关键字,并且默认是大小写敏感的。当我们使用mybatisplus的时候,默认提供的api也只有like()。这里提供一种方式来对原始api进行拓展

java 复制代码
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import org.springframework.stereotype.Component;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.util.Properties;

/**
 * sql查询拦截器
 * <p>
 * 模糊查询时忽略大小写
 * </p>
 * @author lsh
 * @version 1.0
 * @date 2022/5/10 11:13
 */
@Slf4j
@Component
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class FuzzyQueryInterceptor implements Interceptor{
    private static final String FUZZY_QUERY_KEY = "like";
    private static final String IGNORE_FUZZY_QUERY_KEY = "ilike";

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
       // 这里添加判断容器中是否为KingBase获取postgresql的代码
        //拦截StatementHandler,获取Mybatis对象属性
        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = MetaObject
                .forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY, SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY,
                        new DefaultReflectorFactory());
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
        //执行mapper方法的全路径名
        String id = mappedStatement.getId();
        //只拦截查询语句,将like关键字替换成ilike,以忽略大小写
        if (SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())){
            BoundSql boundSql = statementHandler.getBoundSql();
            String sql = boundSql.getSql();
            sql=sql.replaceAll("\\s+"," ");
            if (StringUtils.containsIgnoreCase(sql," like ") || StringUtils.containsIgnoreCase(sql," like ?")){
                String mSql = sql.replaceAll("(?i)"+FUZZY_QUERY_KEY ,IGNORE_FUZZY_QUERY_KEY )
                log.debug(id + ":原始查询语句 ==> " + sql);
                log.debug(id + ":替换后的查询语句 ==> " + mSql);
                //通过反射修改sql语句
                Field field = boundSql.getClass().getDeclaredField("sql");
                field.setAccessible(true);
                field.set(boundSql, mSql);
            }
        }
        //执行结果
        return invocation.proceed();
    }

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

    @Override
    public void setProperties(Properties properties) {
    }
}

直接通过拦截器的方式,将select语句进行分析,当有like的时候将进行转为ilike

相关推荐
小园子的小菜31 分钟前
Redis 核心原理深度解析:从数据结构、IO 模型到持久化机制
数据库·redis·缓存
YUS云生44 分钟前
大模型学习·第44天:Chroma向量数据库与RAG链式组装
数据库·学习
毛驴赶鹿8 小时前
【金仓数据库征文】KES V9性能调优实战记录:从慢SQL排查到全链路优化
数据库·sql
码农阿豪8 小时前
【金仓数据库征文】Mac开发环境|SpringBoot3 + MyBatisPlus对接KES V9 Docker实战全指南
数据库·macos·docker
杨云龙UP8 小时前
MySQL 数据库常用备份工具对比:mysqldump、mydumper 与 XtraBackup
linux·运维·服务器·数据库·mysql·dba·备份恢复
ZENERGY-众壹8 小时前
500个工商业电站压垮数据库?海量光伏时序数据存储的架构取舍
数据库·架构·influxdb·光伏·光伏运维
mubei-1239 小时前
SpringDAO的用法
java·开发语言·数据库
心灵Haven11 小时前
Centos7 + Mysql8.0
mysql·centos
星蓝_starblue12 小时前
零服务器、零数据库!开源growth-board,利用GitHub自动管理刷题/学习/求职全流程
服务器·数据库·程序人生·系统架构·node.js·github·改行学it
三84414 小时前
sqli-labs1-10通关笔记
数据库