Introducing MyBatis-Mate: Enterprise‑Level Features for MyBatis‑Plus
This article introduces MyBatis‑Mate, an official MyBatis‑Plus extension that provides enterprise‑grade capabilities such as sharding, data auditing, field encryption, dictionary binding, sensitive data masking, automatic DDL maintenance, dynamic data‑source switching, performance logging, and fine‑grained data‑scope control, all illustrated with practical code examples.
Today we introduce MyBatis‑Mate, an official MyBatis‑Plus extension that offers enterprise‑level modules including sharding, data auditing, AC‑algorithm based sensitive word filtering, field encryption, dictionary binding, data permissions, automatic DDL generation, and more, enabling more agile and elegant data handling.
Key Features
Dictionary binding
Field encryption
Data masking (sensitive data)
Dynamic table structure maintenance
Data audit records
Data scope (data permissions)
Database sharding, dynamic data source, read/write separation, health check auto‑switch
2. Usage
2.1 Dependency Import
Spring Boot automatically imports the starter dependency:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-mate-starter</artifactId>
<version>1.0.8</version>
</dependency>Annotation package:
<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:
@Component
public class DataDict implements IDataDict {
private Map
SEX_MAP = new ConcurrentHashMap
() {{
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
Annotate a field with @FieldEncrypt to store encrypted data and automatically decrypt on query. The encryption algorithm can be globally configured or specified per annotation.
@FieldEncrypt(algorithm = Algorithm.PBEWithMD5AndDES)
private String password;2.4 Field Sensitive (Data Masking)
Use @FieldSensitive to apply built‑in or custom masking strategies (e.g., name, bank card, phone).
@FieldSensitive(type = "testStrategy")
private String username;
@FieldSensitive(type = SensitiveType.mobile)
private String mobile;Custom strategy configuration:
@Configuration
public class SensitiveStrategyConfig {
@Bean
public ISensitiveStrategy sensitiveStrategy() {
return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");
}
}2.5 DDL Automatic Maintenance
Automatically execute SQL scripts for schema upgrades (supports MySQL and PostgreSQL).
@Component
public class PostgresDdl implements IDdl {
@Override
public List
getSqlFiles() {
return Arrays.asList("db/tag-schema.sql", "D:\\db\\tag-data.sql");
}
}Dynamic execution example:
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 Switching
Use @Sharding to freely switch data sources at mapper level:
@Mapper
@Sharding("mysql")
public interface UserMapper extends BaseMapper
{
@Sharding("postgres")
Long selectByUsername(String username);
}Custom sharding strategy example:
@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 snippet:
mybatis-mate:
sharding:
health: true
primary: mysql
datasource:
mysql:
- key: node1
- key: node2
cluster: slave
postgres:
- key: node12.7 Distributed Transaction Logging
Performance interceptor logs each SQL statement with execution time and can enforce a maximum duration.
@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;
@Override
public Object intercept(Invocation invocation) throws Throwable {
// extract original SQL, measure time, format, log or throw if exceeds maxTime
// ... (implementation omitted for brevity)
}
// other overridden methods and setters/getters
}2.8 Data Permission (Data Scope)
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);Provider implementation builds the WHERE clause dynamically based on the configured columns.
Conclusion
MyBatis‑Mate offers a comprehensive suite of enterprise features for MyBatis‑Plus, covering sharding, data encryption, sensitive data handling, automatic DDL, performance monitoring, and fine‑grained data permissions, making it a powerful tool for backend developers seeking robust data management capabilities.
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.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.