Databases 15 min read

Introducing mybatis-mate: Enterprise‑Level MyBatis Extension for Sharding, Data Encryption, Auditing, and More

The article presents mybatis-mate, an enterprise‑grade MyBatis module that provides sharding, data auditing, sensitive‑word filtering, field encryption, dictionary write‑back, data permission, automatic DDL maintenance, dynamic multi‑datasource switching, and distributed transaction logging, offering developers a more agile and elegant way to handle data.

Java Captain
Java Captain
Java Captain
Introducing mybatis-mate: Enterprise‑Level MyBatis Extension for Sharding, Data Encryption, Auditing, and More

0. Introduction

mybatis-mate is an enterprise‑level MyBatis module that supports sharding, data auditing, sensitive word filtering (Aho‑Corasick algorithm), field encryption, dictionary write‑back (data binding), data permission, automatic table‑structure generation and SQL maintenance, aiming to handle data more agilely and elegantly.

1. Main Features

Dictionary binding

Field encryption

Data desensitization

Dynamic table‑structure maintenance

Data audit records

Data scope (data permission)

Database sharding, dynamic datasource, read‑write separation, automatic health‑check switching

2. Usage

2.1 Dependency Import

Spring Boot automatic dependency annotation package

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-mate-starter</artifactId>
  <version>1.0.8</version>
</dependency>

Annotation (entity sub‑package usage)

<dependency>
  <groupId>com.baomidou</groupId>
  <artifactId>mybatis-mate-annotation</artifactId>
  <version>1.0.8</version>
</dependency>

2.2 Field Data Binding (Dictionary Write‑Back)

Example: map user_sex dictionary to sexText property.

@FieldDict(type = "user_sex", target = "sexText")
private Integer sex;

private String sexText;

Implement IDataDict to provide dictionary data source and inject into Spring.

@Component
public class DataDict implements IDataDict {
    /** fetch from DB or cache */
    private Map<String, String> SEX_MAP = new ConcurrentHashMap<String, String>() {{
        put("0", "女");
        put("1", "男");
    }};

    @Override
    public String getNameByCode(FieldDict fieldDict, String code) {
        System.err.println("字段类型:" + fieldDict.type() + ",编码:" + code);
        return SEX_MAP.get(code);
    }
}

2.3 Field Encryption

Use @FieldEncrypt annotation to encrypt storage and automatically decrypt on query. Global and annotation‑level algorithms can be configured, and custom IEncryptor can be injected.

@FieldEncrypt(algorithm = Algorithm.PBEWithMD5AndDES)
private String password;

2.4 Field Desensitization

Use @FieldSensitive annotation to apply predefined or custom masking strategies (9 built‑in types). Example for Chinese name, bank account, phone number, etc.

@FieldSensitive(type = "testStrategy")
private String username;

@FieldSensitive(type = SensitiveType.mobile)
private String mobile;

Custom strategy can be added via Spring configuration.

@Configuration
public class SensitiveStrategyConfig {
    @Bean
    public ISensitiveStrategy sensitiveStrategy() {
        // custom testStrategy handling
        return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");
    }
}

2.5 Automatic DDL Maintenance

Handles table‑structure upgrades and versioned SQL maintenance for MySQL and PostgreSQL.

@Component
public class PostgresDdl implements IDdl {
    @Override
    public List<String> getSqlFiles() {
        return Arrays.asList("db/tag-schema.sql", "D:\\db\\tag-data.sql");
    }
}

DDL can also be executed dynamically.

ddlScript.run(new StringReader("DELETE FROM user;\nINSERT INTO user (id, username, password, sex, email) VALUES (20, 'Duo', '123456', 0, '[email protected]');"));

2.6 Dynamic Multi‑Datasource Master‑Slave Switching

Use @Sharding annotation to switch data sources freely at mapper level.

@Mapper
@Sharding("mysql")
public interface UserMapper extends BaseMapper
{
    @Sharding("postgres")
    Long selectByUsername(String username);
}

Custom sharding strategy can be defined.

@Component
public class MyShardingStrategy extends RandomShardingStrategy {
    @Override
    public void determineDatasourceKey(String group, Invocation invocation, SqlCommandType sqlCommandType) {
        this.changeDatabaseKey(group, sqlCommandType, keys -> chooseKey(keys, invocation));
    }
}

Configuration example for health check, primary datasource, and node definitions.

mybatis-mate:
  sharding:
    health: true
    primary: mysql
    datasource:
      mysql:
        - key: node1
        - key: node2
          cluster: slave
      postgres:
        - key: node1

2.7 Distributed Transaction Logging

Performance interceptor logs each SQL statement with execution time, optional formatting, and can throw an exception if execution exceeds the configured maxTime.

@Slf4j
@Component
@Intercepts({
    @Signature(type = StatementHandler.class, method = "query", args = {Statement.class, ResultHandler.class}),
    @Signature(type = StatementHandler.class, method = "update", args = {Statement.class}),
    @Signature(type = StatementHandler.class, method = "batch", args = {Statement.class})
})
public class PerformanceInterceptor implements Interceptor {
    private long maxTime = 0;
    private boolean format = false;
    private boolean writeInLog = false;
    // ... (intercept, plugin, setProperties, helper methods) ...
}

2.8 Data Permission

Add @DataScope on mapper methods to enforce row‑level permissions.

@DataScope(type = "test", value = {
    @DataColumn(alias = "u", name = "department_id"),
    @DataColumn(alias = "u", name = "mobile")
})
@Select("select u.* from user u")
List
selectTestList(IPage
page, Long id, @Param("name") String username);

Provide a IDataScopeProvider bean to build WHERE clauses dynamically.

@Bean
public IDataScopeProvider dataScopeProvider() {
    return new AbstractDataScopeProvider() {
        @Override
        protected void setWhere(PlainSelect plainSelect, Object[] args, DataScopeProperty dataScopeProperty) {
            if ("test".equals(dataScopeProperty.getType())) {
                for (DataColumnProperty dataColumn : dataScopeProperty.getColumns()) {
                    if ("department_id".equals(dataColumn.getName())) {
                        Set<String> deptIds = new HashSet<>();
                        deptIds.add("1");
                        deptIds.add("2");
                        deptIds.add("3");
                        deptIds.add("5");
                        ItemsList itemsList = new ExpressionList(deptIds.stream().map(StringValue::new).collect(Collectors.toList()));
                        InExpression inExpression = new InExpression(new Column(dataColumn.getAliasDotName()), itemsList);
                        if (plainSelect.getWhere() == null) {
                            plainSelect.setWhere(new Parenthesis(inExpression));
                        } else {
                            plainSelect.setWhere(new AndExpression(plainSelect.getWhere(), inExpression));
                        }
                    } else if ("mobile".equals(dataColumn.getName())) {
                        LikeExpression likeExpression = new LikeExpression();
                        likeExpression.setLeftExpression(new Column(dataColumn.getAliasDotName()));
                        likeExpression.setRightExpression(new StringValue("%1533%"));
                        plainSelect.setWhere(new AndExpression(plainSelect.getWhere(), likeExpression));
                    }
                }
            }
        }
    };
}

Resulting SQL example:

SELECT u.* FROM user u
WHERE (u.department_id IN ('1','2','3','5')) AND u.mobile LIKE '%1533%' LIMIT 1,10

For more examples, see the paid version repository:

https://gitee.com/baomidou/mybatis-mate-examples

PS: If you find this sharing useful, please like and watch.

JavaDatabaseShardingMyBatisORMdata encryptionData Auditing
Java Captain
Written by

Java Captain

Focused on Java technologies: SSM, the Spring ecosystem, microservices, MySQL, MyCat, clustering, distributed systems, middleware, Linux, networking, multithreading; occasionally covers DevOps tools like Jenkins, Nexus, Docker, ELK; shares practical tech insights and is dedicated to full‑stack Java development.

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.