@Override // SELECT 场景
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
        // 获得 Mapper 对应的数据权限的规则
        List<DataPermissionRule> rules = ruleFactory.getDataPermissionRule(ms.getId());
        if (mappedStatementCache.noRewritable(ms, rules)) { // 如果无需重写，则跳过
            return;
        }

        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
        try {
            // 初始化上下文
            ContextHolder.init(rules);
            // 处理 SQL
            mpBs.sql(parserSingle(mpBs.sql(), null));
        } finally {
            // 添加是否需要重写的缓存
            addMappedStatementCache(ms);
            // 清空上下文
            ContextHolder.clear();
        }
    }
@Test // 存在规则，且不匹配
    public void testBeforeQuery_withMatchRule() {
        try (MockedStatic<PluginUtils> pluginUtilsMock = mockStatic(PluginUtils.class)) {
            // 准备参数
            MappedStatement mappedStatement = mock(MappedStatement.class);
            BoundSql boundSql = mock(BoundSql.class);
            // mock 方法(数据权限)
            when(ruleFactory.getDataPermissionRule(same(mappedStatement.getId())))
                    .thenReturn(singletonList(new DeptDataPermissionRule()));
            // mock 方法(MPBoundSql)
            PluginUtils.MPBoundSql mpBs = mock(PluginUtils.MPBoundSql.class);
            pluginUtilsMock.when(() -> PluginUtils.mpBoundSql(same(boundSql))).thenReturn(mpBs);
            // mock 方法(SQL)
            String sql = "select * from t_user where id = 1";
            when(mpBs.sql()).thenReturn(sql);
            // 针对 ContextHolder 和 MappedStatementCache 暂时不 mock，主要想校验过程中，数据是否正确

            // 调用
            interceptor.beforeQuery(null, mappedStatement, null, null, null, boundSql);
            // 断言
            verify(mpBs, times(1)).sql(
                    eq("SELECT * FROM t_user WHERE id = 1 AND t_user.dept_id = 100"));
            // 断言缓存
            assertTrue(interceptor.getMappedStatementCache().getNoRewritableMappedStatements().isEmpty());
        }
    }