Introduction and Usage Guide for MyBatis-Mate: Enterprise Features for MyBatis-Plus
This article introduces MyBatis-Mate, an official MyBatis‑Plus extension offering enterprise‑level capabilities such as dictionary binding, field encryption, data masking, dynamic DDL maintenance, sharding, multi‑datasource switching, performance logging, and data permission control, with detailed Spring Boot integration examples.
Today we introduce MyBatis‑Mate, an official MyBatis‑Plus tool that provides enterprise‑grade modules including sharding, data auditing, AC‑algorithm sensitive word filtering, field encryption, dictionary binding, data permission, and automatic DDL generation, aiming to handle data more agilely and elegantly.
Key Features
Dictionary binding
Field encryption
Data masking
Dynamic table structure maintenance
Data audit records
Data scope (data permission)
Database sharding, dynamic datasource, read‑write separation, health‑check auto‑switch
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.
@Component
public class DataDict implements IDataDict {
/** Retrieve from DB or cache */
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 encrypt storage and automatically decrypt on query; supports global and annotation‑level algorithms via IEncryptor injection.
@FieldEncrypt(algorithm = Algorithm.PBEWithMD5AndDES)
private String password;2.4 Field Masking
Apply @FieldSensitive to mask data according to predefined SensitiveType strategies (9 built‑in types) or custom strategies.
@FieldSensitive(type = "testStrategy")
private String username;
@FieldSensitive(type = SensitiveType.mobile)
private String mobile;Custom strategy registration example:
@Configuration
public class SensitiveStrategyConfig {
/** Inject custom strategy */
@Bean
public ISensitiveStrategy sensitiveStrategy() {
// custom testStrategy handling
return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");
}
}2.5 DDL Automatic Maintenance
Handles table structure upgrades for 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) {
// custom key selection logic
this.changeDatabaseKey(group, sqlCommandType, keys -> chooseKey(keys, invocation));
}
}2.7 Distributed Transaction Logging
Performance interceptor configuration for SQL timing, formatting, and optional log 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;
// ... interceptor implementation omitted for brevity ...
}2.8 Data Permission
Add @DataScope on mapper methods to enforce row‑level permissions.
// Test data permission for "test" type with mixed pagination
@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);Custom data‑scope provider example (adds department IN clause and mobile LIKE condition).
@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
deptIds = new HashSet<>(Arrays.asList("1", "2", "3", "5"));
ItemsList itemsList = new ExpressionList(deptIds.stream().map(StringValue::new).collect(Collectors.toList()));
InExpression inExpr = new InExpression(new Column(dataColumn.getAliasDotName()), itemsList);
plainSelect.setWhere(plainSelect.getWhere() == null ? new Parenthesis(inExpr) : new AndExpression(plainSelect.getWhere(), inExpr));
} else if ("mobile".equals(dataColumn.getName())) {
LikeExpression likeExpr = new LikeExpression();
likeExpr.setLeftExpression(new Column(dataColumn.getAliasDotName()));
likeExpr.setRightExpression(new StringValue("%1533%"));
plainSelect.setWhere(new AndExpression(plainSelect.getWhere(), likeExpr));
}
}
}
}
};
}Final SQL example produced by the above configuration:
SELECT u.* FROM user u
WHERE (u.department_id IN ('1', '2', '3', '5'))
AND u.mobile LIKE '%1533%'
LIMIT 1, 10For more MyBatis‑Mate usage examples, visit the official repository:
https://gitee.com/baomidou/mybatis-mate-examples
Selected Java Interview Questions
A professional Java tech channel sharing common knowledge to help developers fill gaps. Follow us!
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.