Backend Development 9 min read

Implementing Data Isolation in Java Applications Using MyBatis Interceptor and Custom Annotations

This article describes a practical approach to achieve environment‑based data isolation in Java services by adding an env field to tables, using a MyBatis interceptor to rewrite SQL, and defining custom annotations with AOP to control the isolation logic, while sharing code snippets and lessons learned.

Selected Java Interview Questions
Selected Java Interview Questions
Selected Java Interview Questions
Implementing Data Isolation in Java Applications Using MyBatis Interceptor and Custom Annotations

Data Isolation Background

In a pre‑release, gray, and online environment sharing a single database, each table originally had an env column to distinguish data. Adding the column to dozens of existing tables caused massive data migration and compatibility challenges.

Before Isolation

Only one core table had the env field; other tables lacked it, leading to accidental data leakage from pre‑release to production.

Isolation Transformation

All new tables received an env column initialized to all so that historical data could be accessed by any environment. The application reads the current environment from application.properties and injects it into SQL statements.

SELECT XXX FROM tableName WHERE env = ${environmentValue} and ${condition}

Solution Design

The naive approach of adding env to every DO, Mapper, and XML was rejected. Instead, a custom MyBatis interceptor was created to handle the logic centrally.

Business code does not need to be modified.

Avoids repetitive field additions and reduces error risk.

Facilitates future extensions.

Final Implementation

In the interceptor, INSERT statements automatically fill the environment field, and SELECT statements add an env IN (${currentEnv},'all') condition to support both current and historical data.

SELECT xxx FROM ${tableName} WHERE env IN (${currentEnv},'all') AND ${otherCondition}

The interceptor uses JSqlParser to rewrite SQL dynamically.

@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})})
@Component
public class EnvIsolationInterceptor implements Interceptor {
    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // rewrite SQL, fill env parameter, etc.
        return invocation.proceed();
    }
}

Further Refactoring

To avoid scattering environment‑skip logic, a custom annotation @InvokeChainSkipEnvRule with AOP was introduced. Developers annotate entry methods, specifying environments and tables to skip.

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface InvokeChainSkipEnvRule {
    boolean isKip() default true;
    String[] skipEnvList() default {};
    String[] skipTableList() default {};
}

Example usage:

@GetMapping("/importSignedUserData")
@InvokeChainSkipEnvRule(skipEnvList = {"pre"}, skipTableList = {"project"})
public void importSignedUserData(HttpServletRequest request, HttpServletResponse response) {
    // ...
}

Challenges & Reflections

Issues such as ThreadLocal misuse and context restoration caused null environment values. The solution emphasizes keeping business and infrastructure code separate, using a dedicated ThreadLocal, and limiting modifications to a single interception point.

Key takeaways include the importance of early architectural decisions, avoiding ad‑hoc field additions, and leveraging custom annotations for clean, reusable isolation logic.

Conclusion

The case demonstrates a robust way to achieve both data isolation and selective sharing across environments by combining a MyBatis interceptor with custom annotations, providing a reference for similar backend challenges.

Javabackend developmentMyBatisCustom AnnotationData Isolation
Selected Java Interview Questions
Written by

Selected Java Interview Questions

A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!

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.