@InterceptorIgnore 是 MyBatis-Plus 提供的一个非常实用的注解,用于在特定的 CRUD 操作中临时忽略某些全局拦截器的行为。它能帮助开发者在需要时灵活绕过如分页、租户、数据权限、SQL 性能监控等全局拦截逻辑,适用于特定场景下的性能优化或业务绕行。


一、核心概念

1. 什么是 @InterceptorIgnore

@InterceptorIgnore 是一个作用于 Mapper 接口方法Service 方法(需配合 AOP)上的注解,用于在执行 SQL 时临时关闭某些全局拦截器的功能

2. 主要作用

  • 跳过分页拦截:某些查询不需要分页,避免 PageHelper 或 MP 分页插件生效。
  • 绕过租户拦截:多租户系统中,某些操作需要跨租户查询。
  • 禁用数据权限:管理员操作时绕过数据权限控制。
  • 跳过性能监控:对高频、简单 SQL 关闭慢 SQL 监控,减少性能损耗。

3. 支持的拦截器类型(常见)

拦截器类型 对应 @InterceptorIgnore 属性 说明
分页拦截器 pagination 跳过分页逻辑
租户拦截器 tenantLine 忽略租户字段自动注入
动态表名 dynamicTableName 不进行表名动态替换
数据权限 dataPermission 跳过数据权限过滤
SQL 性能分析 blockAttack 禁用 SQL 防注入攻击检查

二、操作步骤(非常详细)

步骤 1:引入 MyBatis-Plus 依赖

确保项目中已引入 MyBatis-Plus(以 Spring Boot 为例):

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

步骤 2:配置全局拦截器(以分页和租户为例)

示例:配置分页和租户拦截器

@Configuration
@MapperScan("com.example.mapper")
public class MyBatisPlusConfig {

    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();

        // 1. 分页插件
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));

        // 2. 租户插件
        TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
        tenantInterceptor.setTenantLineHandler(new TenantLineHandler() {
            @Override
            public String getTenantId() {
                return "10001"; // 实际应从上下文获取
            }

            @Override
            public String getTenantIdColumn() {
                return "tenant_id";
            }
        });
        interceptor.addInnerInterceptor(tenantInterceptor);

        return interceptor;
    }
}

步骤 3:使用 @InterceptorIgnore 忽略特定拦截器

场景 1:忽略分页拦截器

在 Mapper 接口方法上使用:

public interface UserMapper extends BaseMapper<User> {

    /**
     * 此方法不进行分页处理,即使外部调用了分页
     */
    @InterceptorIgnore(pagination = "true")
    List<User> selectAllWithoutPage();
}

说明:调用此方法时,即使 ThreadLocal 中有分页参数,也不会生效。

场景 2:忽略租户拦截器

@InterceptorIgnore(tenantLine = "true")
List<User> selectAllAcrossTenants();

说明:查询所有租户的数据,不自动添加 tenant_id = ? 条件。

场景 3:同时忽略多个拦截器

@InterceptorIgnore(pagination = "true", tenantLine = "true")
List<User> selectAllForAdmin();

说明:管理员操作,既不分页也不受租户限制。

场景 4:在 Service 层使用(需开启 AOP)

@Service
public class UserService {

    @Autowired
    private UserMapper userMapper;

    @InterceptorIgnore(pagination = "true")
    public List<User> getAllUsers() {
        return userMapper.selectList(null); // 此调用将忽略分页
    }
}

注意:Service 方法使用 @InterceptorIgnore 需确保 AOP 生效(方法不能是 private,且在同一类中调用会失效)。


三、常见错误

错误 原因 解决方案
@InterceptorIgnore 不生效 注解位置错误或拦截器未正确配置 确保注解在 Mapper 方法 上,且对应拦截器已注册
租户条件仍被添加 tenantLine = "true" 拼写错误或大小写问题 使用 "true" 字符串,注意大小写
分页仍生效 其他地方手动设置了分页 检查是否在代码中显式调用 PageHelper.startPage()new Page<>()
Service 层注解无效 AOP 未生效(如 self-invocation) 使用 @Autowired 调用代理对象,避免直接调用本类方法

四、注意事项

  1. 作用范围@InterceptorIgnore 只对当前方法生效,不影响其他方法。
  2. 字符串值:属性值为 "true""false",不是布尔类型。
  3. 优先级@InterceptorIgnore 优先级高于全局拦截器配置。
  4. 不支持嵌套:若 A 方法调用 B 方法,B 有 @InterceptorIgnore,但 A 没有,则可能不生效(AOP 限制)。
  5. 谨慎使用:绕过租户或数据权限可能带来安全风险,仅用于可信场景(如后台管理)。

五、使用技巧

1. 动态控制(结合 SpEL,需自定义)

MyBatis-Plus 原生不支持 SpEL,但可通过自定义注解 + AOP 实现:

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@InterceptorIgnore
public @interface DynamicIgnore {
    String pagination() default "";
}

进阶:结合 Spring AOP 解析 SpEL 表达式动态决定是否忽略。

2. 与 @DS 数据源切换结合

@DS("slave")
@InterceptorIgnore(pagination = "true")
List<User> selectFromSlaveWithoutPage();

用途:从从库查询大量数据,不分页,减轻主库压力。

3. 高频查询关闭监控

@InterceptorIgnore(blockAttack = "true") // 关闭 SQL 防攻击检查
User findByIdFast(Long id);

适用:极高频的查询接口,减少拦截器开销。


六、最佳实践与性能优化

最佳实践

  1. 最小化使用:仅在必要时使用 @InterceptorIgnore,避免滥用导致逻辑混乱。
  2. 命名规范:方法名体现“忽略”语义,如 selectWithoutPaginationqueryAcrossTenants
  3. 权限控制:绕过租户或权限的方法必须进行严格的访问控制(如 @PreAuthorize)。
  4. 文档说明:在方法上添加注释,说明为何忽略拦截器。

性能优化

  1. 减少拦截器开销:对简单查询(如根据主键查)关闭不必要的拦截器,提升吞吐量。
  2. 批量操作优化:批量插入/更新时,可考虑关闭 SQL 性能分析拦截器。
  3. 异步任务绕行:定时任务或数据同步任务中,使用 @InterceptorIgnore 避免被业务拦截器干扰。

总结

@InterceptorIgnore 是 MyBatis-Plus 中一个“精准控制拦截器行为”的利器。通过它,你可以在特定方法中:

✅ 跳过分页
✅ 绕过租户隔离
✅ 关闭数据权限
✅ 提升高频查询性能