Backend Development 14 min read

Implementing a Data Permission Interceptor for MyBatis-Plus Using Custom Annotations

This article explains how to create a custom @UserDataPermission annotation and a MyBatis-Plus interceptor that automatically injects WHERE clauses based on the current user's role, enabling fine‑grained data access control without modifying each mapper method.

Top Architect
Top Architect
Top Architect
Implementing a Data Permission Interceptor for MyBatis-Plus Using Custom Annotations

In many development scenarios, you need to restrict data visibility based on the current user's role, and you may want to apply this restriction without modifying every mapper method.

This article demonstrates how to use MyBatis-Plus interceptors combined with a custom annotation to automatically inject WHERE clauses that enforce data permissions.

Steps:

Create a custom annotation @UserDataPermission :

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface UserDataPermission {
}

Implement an interceptor class that extends JsqlParserSupport and implements InnerInterceptor , overriding beforeQuery and processSelect to modify the SQL.

Write a handler that builds the permission SQL fragment (e.g., equality for self‑data, IN expression for department data) based on the logged‑in user and their roles.

Register the interceptor in a MybatisPlusInterceptor bean, adding it before the pagination interceptor.

If the project already configures a MybatisPlusInterceptor , insert the data‑permission interceptor into the existing bean to avoid affecting other configurations.

Apply the @UserDataPermission annotation on mapper methods (including those inherited from BaseMapper ) to activate the filter.

The article also provides an advanced version that supports role‑based scopes (ALL, DEPT, MYSELF) and shows how to retrieve role information from remote services, construct appropriate SQL expressions, and integrate the handler into the interceptor.

public class MyDataPermissionInterceptor extends JsqlParserSupport implements InnerInterceptor {
    private MyDataPermissionHandler dataPermissionHandler;

    @Override
    public void beforeQuery(Executor executor, MappedStatement ms, Object parameter,
                            RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
            throws SQLException {
        if (InterceptorIgnoreHelper.willIgnoreDataPermission(ms.getId())) {
            return;
        }
        PluginUtils.MPBoundSql mpBs = PluginUtils.mpBoundSql(boundSql);
        mpBs.sql(this.parserSingle(mpBs.sql(), ms.getId()));
    }

    @Override
    protected void processSelect(Select select, int index, String sql, Object obj) {
        // modify the SELECT's WHERE clause based on permission logic
    }

    private void setWhere(PlainSelect plainSelect, String whereSegment) {
        // build and set the permission expression
    }
}

Finally, remember to add the interceptor to the MyBatis‑Plus plugin, ensure the permission field (e.g., creator_code ) exists in your tables, and adjust the field name if needed (e.g., dept_code ).

javaBackend DevelopmentInterceptorMyBatis-PlusAnnotationData Permission
Top Architect
Written by

Top Architect

Top Architect focuses on sharing practical architecture knowledge, covering enterprise, system, website, large‑scale distributed, and high‑availability architectures, plus architecture adjustments using internet technologies. We welcome idea‑driven, sharing‑oriented architects to exchange and learn together.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.