Backend Development 10 min read

Master Enterprise Data Management with MyBatis‑Mate: Sharding, Encryption & Auditing

This article introduces MyBatis‑Mate, an official MyBatis‑Plus extension that provides enterprise‑grade features such as sharding, data auditing, field encryption, sensitive data masking, dictionary binding, dynamic DDL maintenance, and flexible data‑source switching, complete with usage examples and code snippets.

macrozheng
macrozheng
macrozheng
Master Enterprise Data Management with MyBatis‑Mate: Sharding, Encryption & Auditing
Today we introduce a MyBatis‑Plus official tool: mybatis‑mate, an enterprise‑level module supporting sharding, data audit, sensitive data filtering (AC algorithm), field encryption, dictionary binding, data permission, automatic DDL generation, and other SQL maintenance features for more agile and elegant data handling.

1. Main Features

Dictionary binding

Field encryption

Data masking

Dynamic table structure maintenance

Data audit records

Data scope (data permission)

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

2. Usage

2.1 Dependency Import

Spring Boot automatic dependency annotation package

<code>&lt;dependency&gt;
  &lt;groupId&gt;com.baomidou&lt;/groupId&gt;
  &lt;artifactId&gt;mybatis-mate-starter&lt;/artifactId&gt;
  &lt;version&gt;1.0.8&lt;/version&gt;
&lt;/dependency&gt;</code>

Annotation package for entity sub‑package usage

<code>&lt;dependency&gt;
  &lt;groupId&gt;com.baomidou&lt;/groupId&gt;
  &lt;artifactId&gt;mybatis-mate-annotation&lt;/artifactId&gt;
  &lt;version&gt;1.0.8&lt;/version&gt;
&lt;/dependency&gt;</code>

2.2 Dictionary Binding

Map the "user_sex" dictionary to the "sexText" property

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

private String sexText;</code>

Implement IDataDict to provide dictionary data source

<code>@Component
public class DataDict implements IDataDict {
    private Map<String, String> SEX_MAP = new ConcurrentHashMap&lt;&gt;() {{
        put("0", "女");
        put("1", "男");
    }};

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

2.3 Field Encryption

Annotate a field with @FieldEncrypt to store encrypted data and automatically decrypt on query. Global and per‑field encryption algorithms can be configured, and custom IEncryptor implementations can be injected.

<code>@FieldEncrypt(algorithm = Algorithm.PBEWithMD5AndDES)
private String password;</code>

2.4 Data Masking

Use @FieldSensitive to apply built‑in or custom masking strategies (e.g., name, bank card, phone, email, ID, etc.).

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

@FieldSensitive(type = SensitiveType.mobile)
private String mobile;</code>

Register a custom strategy in the Spring container

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

2.5 DDL Automatic Maintenance

Supports MySQL and PostgreSQL for automatic table‑structure updates during version releases.

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

Dynamic execution example

<code>ddlScript.run(new StringReader("DELETE FROM user;\n" +
        "INSERT INTO user (id, username, password, sex, email) VALUES\n" +
        "(20, 'Duo', '123456', 0, '[email protected]');"));</code>

2.6 Dynamic Multi‑DataSource Switching

The @Sharding annotation enables effortless switching between data sources at the mapper level.

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

Custom sharding strategy example

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

2.7 Data Permission

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

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

Provider implementation that builds WHERE clauses based on the defined scope

<code>@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<>(Arrays.asList("1","2","3","5"));
                        ItemsList itemsList = new ExpressionList(deptIds.stream().map(StringValue::new).collect(Collectors.toList()));
                        InExpression inExpression = new InExpression(new Column(dataColumn.getAliasDotName()), itemsList);
                        plainSelect.setWhere(plainSelect.getWhere() == null ? new Parenthesis(inExpression) : new AndExpression(plainSelect.getWhere(), inExpression));
                    } else if ("mobile".equals(dataColumn.getName())) {
                        LikeExpression like = new LikeExpression();
                        like.setLeftExpression(new Column(dataColumn.getAliasDotName()));
                        like.setRightExpression(new StringValue("%1533%"));
                        plainSelect.setWhere(new AndExpression(plainSelect.getWhere(), like));
                    }
                }
            }
        }
    };
}
</code>

Resulting SQL example

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

3. Conclusion

The author has used MyBatis‑Plus for over four years, noting that it greatly improves development efficiency, unifies code style across the enterprise, and reduces maintenance costs. For enterprises that need advanced data handling, MyBatis‑Mate offers a powerful solution.

JavadatabaseSpring BootData ShardingMyBatisData AuditingField Encryption
macrozheng
Written by

macrozheng

Dedicated to Java tech sharing and dissecting top open-source projects. Topics include Spring Boot, Spring Cloud, Docker, Kubernetes and more. Author’s GitHub project “mall” has 50K+ stars.

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.