mybatis-mate: An Enterprise‑Level MyBatis‑Plus Extension for Sharding, Data Auditing, Encryption, and More
This article introduces mybatis-mate, an official MyBatis‑Plus extension that provides enterprise‑grade features such as sharding, multi‑datasource support, data auditing, field encryption, sensitive‑data masking, automatic DDL maintenance, dynamic datasource switching, distributed transaction logging, and fine‑grained data permission control, with detailed usage examples and configuration snippets for Spring Boot projects.
Main Features
Dictionary binding
Field encryption
Data masking (sensitive data)
Dynamic table structure maintenance
Data audit records
Data scope (data permission)
Database sharding, dynamic datasource, read/write separation, automatic health‑check and failover
2. Usage
2.1 Dependency Import
Spring Boot automatic dependency:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-mate-starter</artifactId>
<version>1.0.8</version>
</dependency>Annotation package (entity sub‑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 the user_sex dictionary to the 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
Use @FieldEncrypt to store encrypted values; decryption happens automatically on query. Global and per‑field algorithms are configurable, and custom encryptors can be injected via IEncryptor .
@FieldEncrypt(algorithm = Algorithm.PBEWithMD5AndDES)
private String password;2.4 Field Sensitive (Data Masking)
Apply @FieldSensitive to mask data according to built‑in or custom strategies.
@FieldSensitive(type = "testStrategy")
private String username;
@FieldSensitive(type = SensitiveType.mobile)
private String mobile;Custom strategy example:
@Configuration
public class SensitiveStrategyConfig {
@Bean
public ISensitiveStrategy sensitiveStrategy() {
// custom "testStrategy" adds ***test*** suffix
return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");
}
}2.5 DDL Automatic Maintenance
Supports MySQL and PostgreSQL for automatic schema creation and version‑based SQL execution.
@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;\n" +
"INSERT INTO user (id, username, password, sex, email) VALUES (20, 'Duo', '123456', 0, '[email protected]');"
));2.6 Dynamic Multi‑Datasource Master/Slave Switching
Use @Sharding to switch datasources freely 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));
}
}2.7 Distributed Transaction Log Printing
Performance interceptor prints each SQL statement with execution time, supports optional formatting and log‑file writing.
@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;
// ... (implementation omitted for brevity) ...
}2.8 Data Permission
Define data scope at mapper level with @DataScope and @DataColumn annotations.
@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 custom IDataScopeProvider to build the WHERE clause 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 col : dataScopeProperty.getColumns()) {
if ("department_id".equals(col.getName())) {
// IN condition for department IDs
Set
deptIds = new HashSet<>(Arrays.asList("1","2","3","5"));
ItemsList items = new ExpressionList(deptIds.stream().map(StringValue::new).collect(Collectors.toList()));
InExpression in = new InExpression(new Column(col.getAliasDotName()), items);
plainSelect.setWhere(plainSelect.getWhere() == null ? new Parenthesis(in) : new AndExpression(plainSelect.getWhere(), in));
} else if ("mobile".equals(col.getName())) {
// LIKE condition for mobile
LikeExpression like = new LikeExpression();
like.setLeftExpression(new Column(col.getAliasDotName()));
like.setRightExpression(new StringValue("%1533%"));
plainSelect.setWhere(new AndExpression(plainSelect.getWhere(), like));
}
}
}
}
};
}Conclusion
The article demonstrates how mybatis-mate can simplify enterprise‑level data handling in Spring Boot applications, covering configuration, code examples, and advanced features such as sharding, encryption, auditing, and fine‑grained permission control.
Java Architect Essentials
Committed to sharing quality articles and tutorials to help Java programmers progress from junior to mid-level to senior architect. We curate high-quality learning resources, interview questions, videos, and projects from across the internet to help you systematically improve your Java architecture skills. Follow and reply '1024' to get Java programming resources. Learn together, grow 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.