在 MyBatis Plus 中,你可以使用自定义的拦截器来动态修改 SQL 语句。MyBatis Plus 提供了一个 InnerInterceptor 接口,你可以实现这个接口来创建自己的拦截器。下面是一个简单的例子,展示如何创建一个拦截器来动态修改 SQL 语句。
 

创建自定义拦截器

首先,你需要创建一个类实现 InnerInterceptor 接口,并重写其中的方法。这里主要关注 beforeQuery 方法,因为它允许你在 SQL 查询之前进行修改。

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.interceptor.InnerInterceptor;
import com.baomidou.mybatisplus.core.metadata.TableFieldInfo;
import com.baomidou.mybatisplus.core.metadata.TableInfoHelper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ParameterMode;
import org.apache.ibatis.plugin.Intercept;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

import java.sql.Connection;
import java.util.List;
import java.util.Properties;

@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
public class CustomInterceptor implements InnerInterceptor {

    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
        Object parameter = null;
        if (invocation.getArgs().length > 1) {
            parameter = invocation.getArgs()[1];
        }
        
        BoundSql boundSql = mappedStatement.getBoundSql(parameter);
        String sql = boundSql.getSql();
        
        // 动态修改 SQL 语句
        sql = modifySql(sql, mappedStatement, parameter);
        
        // 更新 BoundSql 对象
        BoundSql newBoundSql = new BoundSql(mappedStatement.getConfiguration(), sql, boundSql.getParameterMappings(), boundSql.getParameterObject());
        
        MetaObject metaStatement = MetaObject.forObject(mappedStatement);
        metaStatement.setValue("boundSql", newBoundSql);
        
        return invocation.proceed();
    }

    private String modifySql(String sql, MappedStatement mappedStatement, Object parameter) {
        // 根据需要修改 SQL
        // 例如添加特定的查询条件
        return sql + " AND some_condition = ?";
    }

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

    @Override
    public void setProperties(Properties properties) {
        // 设置拦截器的属性
    }
}

注册拦截器

创建好拦截器之后,你需要在 MyBatis Plus 的配置中注册这个拦截器。这通常是在Spring Boot应用的配置类中完成的。

import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class MybatisPlusConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return new PaginationInterceptor();
    }

    @Bean
    public InnerInterceptor customInterceptor() {
        return new CustomInterceptor();
    }
}

注意事项
        在上面的例子中,modifySql 方法是修改 SQL 的地方。你可以根据需求添加任何必要的逻辑来修改 SQL 语句。
        确保在修改 SQL 后更新 BoundSql 对象,以便 MyBatis 能够正确执行新的 SQL 语句。
        当使用 @Intercepts 注解时,请确保签名(type, method, args)与 MyBatis 中的实际方法匹配。
        在 Spring Boot 应用中,确保拦截器被正确注册并且在 MyBatis Plus 的生命周期内可用。
这样,你就可以在 MyBatis Plus 中使用自定义拦截器来动态修改 SQL 语句了。这在需要添加通用查询条件、多租户支持等场景下非常有用。

点赞(0) 打赏

评论列表 共有 0 条评论

暂无评论

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部