mybatis-mate – Enterprise‑level MyBatis Extension for Sharding, Auditing, Encryption, and Data Permissions
The article introduces mybatis-mate, an enterprise‑grade MyBatis module that supports sharding, multi‑datasource, data auditing, field encryption, sensitive‑data masking, automatic DDL maintenance, performance logging, and fine‑grained data‑scope control, providing code examples and configuration guidelines for Spring Boot projects.
mybatis-mate is an enterprise‑level extension for MyBatis (MP) that offers a comprehensive set of data‑management features, including sharding, multi‑datasource handling, data auditing, field encryption, sensitive‑data masking, automatic DDL generation, performance logging, and fine‑grained data‑scope control.
Main Features
Dictionary binding (field‑dict)
Field encryption with customizable algorithms
Data masking with built‑in SensitiveType strategies
Automatic DDL maintenance for MySQL and PostgreSQL
Dynamic multi‑datasource master/slave switching via @Sharding
Distributed transaction log printing
Data‑scope (row‑level) permission control
Dependency Import
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-mate-starter</artifactId>
<version>1.0.8</version>
</dependency> <dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-mate-annotation</artifactId>
<version>1.0.8</version>
</dependency>Field Dictionary Binding Example
@FieldDict(type = "user_sex", target = "sexText")
private Integer sex;
private String sexText;The IDataDict implementation provides the dictionary source, e.g. mapping "0" → "女", "1" → "男".
@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);
}
}Field Encryption Example
@FieldEncrypt(algorithm = Algorithm.PBEWithMD5AndDES)
private String password;Encryption keys can be configured globally or per‑field, and custom IEncryptor implementations can be injected.
Data Masking Example
@FieldSensitive(type = "testStrategy")
private String username;
@FieldSensitive(type = SensitiveType.mobile)
private String mobile;Custom strategies can be added via a Spring @Configuration bean.
@Configuration
public class SensitiveStrategyConfig {
@Bean
public ISensitiveStrategy sensitiveStrategy() {
return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");
}
}Automatic DDL Maintenance
@Component
public class PostgresDdl implements IDdl {
@Override
public List
getSqlFiles() {
return Arrays.asList("db/tag-schema.sql", "D:\\db\\tag-data.sql");
}
}The same interface can be implemented for MySQL, supporting static and dynamic SQL execution.
@Component
public class MysqlDdl implements IDdl {
@Override
public void sharding(Consumer
consumer) {
String group = "mysql";
ShardingGroupProperty sgp = ShardingKey.getDbGroupProperty(group);
if (sgp != null) {
sgp.getMasterKeys().forEach(key -> {
ShardingKey.change(group + key);
consumer.accept(this);
});
sgp.getSlaveKeys().forEach(key -> {
ShardingKey.change(group + key);
consumer.accept(this);
});
}
}
@Override
public List
getSqlFiles() {
return Arrays.asList("db/user-mysql.sql");
}
}Dynamic Multi‑Datasource Switching
@Mapper
@Sharding("mysql")
public interface UserMapper extends BaseMapper
{
@Sharding("postgres")
Long selectByUsername(String username);
}A custom sharding strategy can be created by extending RandomShardingStrategy and overriding determineDatasourceKey .
@Component
public class MyShardingStrategy extends RandomShardingStrategy {
@Override
public void determineDatasourceKey(String group, Invocation invocation, SqlCommandType sqlCommandType) {
this.changeDatabaseKey(group, sqlCommandType, keys -> chooseKey(keys, invocation));
}
}Performance Interceptor (SQL Logging)
@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 method prints execution time and formatted SQL
// setProperties reads maxTime, format from configuration
}Data‑Scope Permission Control
@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);A custom IDataScopeProvider can inject the WHERE clause dynamically.
@Bean
public IDataScopeProvider dataScopeProvider() {
return new AbstractDataScopeProvider() {
@Override
protected void setWhere(PlainSelect plainSelect, Object[] args, DataScopeProperty dataScopeProperty) {
// Example adds department IN clause and mobile LIKE clause
}
};
}Configuration Example
mybatis-mate:
sharding:
health: true # enable health check
primary: mysql # default datasource
datasource:
mysql:
- key: node1
- key: node2
cluster: slave
postgres:
- key: node1The article concludes with a link to the paid version and the public example repository:
https://gitee.com/baomidou/mybatis-mate-examples
Architecture Digest
Focusing on Java backend development, covering application architecture from top-tier internet companies (high availability, high performance, high stability), big data, machine learning, Java architecture, and other popular fields.
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.