MyBatis-Plus入门教程 MyBatis-Plus 扩展-企业高级特性

2024-02-25 开发教程 MyBatis-Plus入门教程 匿名 4

mybatis-mate​ 为 mp 企业级模块,旨在更敏捷优雅处理数据。

mybatis-mate 示例 :传送门

数据审计(对账)

mybatis-mate-audit

  • 对比两对象属性差异,例如:银行流水对账。
// 1,异步回调,注意 @EnableAsync 开启异步
applicationEventPublisher.publishEvent(new DataAuditEvent((t) -> {
List<Change> changes = t.apply(newVersion, oldVersion);
for (Change valueChange : changes) {
ValueChange change = (ValueChange) valueChange;
System.err.println(String.format("%s不匹配,期望值 %s 实际值 %s", change.getPropertyName(), change.getLeft(), change.getRight()));
}
}));
// 2,手动调用对比
DataAuditor.compare(obj1, obj2);

数据敏感词过滤

mybatis-mate-sensitive-words

  • 数据敏感词过滤(AC 算法)配置完处理器,框架自动处理请求的所有字符串敏感词过滤,支持嵌套关键词让敏感词无处遁形。
  • 数据库自维护敏感词库(免费、可控),默认加载缓存词根支持指定重新加载词库。

数据范围(数据权限)

mybatis-mate-datascope

  • 注解 ​@DataScope
属性类型 必须指定默认值描述
typeString""范围类型,用于区分对于业务分类,默认空
valueDataColumn[]{}数据权限字段,支持多字段组合
ignorebooleanfalse忽略权限处理逻辑 true 是 false 否
  • 注解 ​@DataColumn
属性类型必须指定默认值描述
aliasString""关联表别名
nameString字段名
  • 行级粒度权限控制,例如:上级部门可以查看子部门信息。
// 测试 test 类型数据权限范围,混合分页模式
@DataScope(type = "test", value = {
// 关联表 user 别名 u 指定部门字段权限
@DataColumn(alias = "u", name = "department_id"),
// 关联表 user 别名 u 指定手机号字段(自己判断处理)
@DataColumn(alias = "u", name = "mobile")
})
@Select("select u.* from user u")
List<User> selectTestList(IPage<User> page, Long id, @Param("name") String username);
// 测试数据权限,最终执行 SQL 语句
SELECT u.* FROM user u WHERE (u.department_id IN ('1', '2', '3', '5')) AND u.mobile LIKE '%1533%' LIMIT 1,10

关于IDataScopeProvider的说明

请注意必须注入 ​IDataScopeProvider实现类处理数据权限,关于数据传参支持 2 种方式:

  • 自定义 ​mapper方法通过方法参数传递,在 ​setWhere方法 ​Object[] args参数中获取
  • 利用 ​ThreadLocal传递参数,你可以拦截 ​controller层或者 ​service层设置数据权限处理参数,更多可以参考

表结构自动维护

mybatis-mate-ddl-mysqlmybatis-mate-ddl-postgres

  • 数据库 ​Schema初始化,升级 SQL 自动维护,区别于 ​flyway支持分表库、可控制代码执行 SQL 脚本
  • 首次会在数据库中生成 ​ddl_history表,每次执行SQL脚本会自动维护版本信息。
@Component
public class MysqlDdl implements IDdl {
/**
* 执行 SQL 脚本方式
*/
@Override
public List<String> getSqlFiles() {
return Arrays.asList(
"db/tag-schema.sql",
"D:\\db\\tag-data.sql"
);
}
}
// 切换到 mysql 从库,执行 SQL 脚本
ShardingKey.change("mysqlt2");
ddlScript.run(new StringReader("DELETE FROM user;\n" +
"INSERT INTO user (id, username, password, sex, email) VALUES\n" +
"(20, 'Duo', '123456', 0, 'Duo@baomidou.com');"));

字段数据绑定(字典回写)

mybatis-mate-dict

  • 注解 ​@FieldBind
属性类型必须指定默认值描述
shardingString""分库分表数据源指定
typeString类型(用于区分不同业务)
targetString目标显示属性(待绑定属性,注意非数据库字段请排除)
  • 数据库 sex 值 0、1 自动映射为 男、女
  • 可以绑定映射为对象,例如:根据订单 ID 映射 订单对象或者编号
@FieldBind(type = "user_sex", target = "sexText")
private Integer sex;
// 绑定显示属性,非表字典(排除)
@TableField(exist = false)
private String sexText;
  • 绑定业务处理类需要实现 ​IDataBind接口,注入 spring 容器
@Component
public class DataBind implements IDataBind {
...
}

虚拟属性绑定

mybatis-mate-jsonbind

  • 注解 ​@JsonBind
@JsonBind("绑定类型")
public class User {
...
}
  • 返回 Json 虚拟属性绑定策略
@Component
public class JsonBindStrategy implements IJsonBindStrategy {
@Override
public Map<String, Function<Object, Map<String, Object>>> getStrategyFunctionMap() {
return new HashMap<String, Function<Object, Map<String, Object>>>(16) {
{
// 注入虚拟节点
put(Type.departmentRole, (obj) -> new HashMap(2) {{
User user = (User) obj;
// 枚举类型转换
put("statusText", StatusEnum.get(user.getStatus()).getDesc());
// 可调用数据库查询角色信息
put("roleName", "经理");
}});
}
};
}
}

字段加密解密

mybatis-mate-encrypt

  • 注解 ​@FieldEncrypt
属性类型必须指定默认值描述
passwordString""加密密码
algorithmAlgorithmPBEWithMD5AndDESPBE MD5 DES 混合算法
encryptorClassIEncryptor加密处理器
  • 算法 ​Algorithm
算法描述
MD5_3232 位 md5 算法
MD5_1616 位 md5 算法
BASE6464 个字符来表示任意二进制数据算法
AESAES 对称算法
RSA非对称加密算法
SM2国密 SM2 非对称加密算法,基于 ECC
SM3国密 SM3 消息摘要算法,可以用 MD5 作为对比理解
SM4国密 SM4 对称加密算法,无线局域网标准的分组数据算法
PBEWithMD5AndDES混合算法
PBEWithMD5AndTripleDES混合算法
PBEWithHMACSHA512AndAES_256混合算法
PBEWithSHA1AndDESede混合算法
PBEWithSHA1AndRC2_40混合算法

注意

MD5算法为不可逆算法,存储数据库及查询结果都是密文 ​SM4算法必须依赖 ​bouncycastle加密库 混合算法必须依赖 ​jasypt加密库 【注意】查询返回加密对象必须包含加密注解信息,单纯的返回某个 ​String或者 ​List某个集合是无法解密的。

  • 注解 ​FieldEncrypt实现数据加解密,支持多种加密算法
@FieldEncrypt
private String email;

字段脱敏

mybatis-mate-sensitive-jackson

  • 注解 ​@FieldSensitive
  • 注解 ​FieldSensitive实现数据脱敏,内置 手机号、邮箱、银行卡号 等 9 种常用脱敏规则
@FieldSensitive("testStrategy")
private String username;
@Configuration
public class SensitiveStrategyConfig {
/**
* 注入脱敏策略
*/
@Bean
public ISensitiveStrategy sensitiveStrategy() {
// 自定义 testStrategy 类型脱敏处理
return new SensitiveStrategy().addStrategy("testStrategy", t -> t + "***test***");
}
}
// 跳过脱密处理,用于编辑场景
RequestDataTransfer.skipSensitive();

多数据源分库分表(读写分离)

mybatis-mate-sharding

  • 注解 ​@Sharding
属性类型必须指定默认值描述
valueString""分库组名,空使用默认主数据源
strategyClassRandomShardingStrategy分库&分表策略
  • 配置
mybatis-mate:
sharding:
health: true # 健康检测
primary: mysql # 默认选择数据源
datasource:
mysql: # 数据库组
- key: node1
...
- key: node2
cluster: slave # 从库读写分离时候负责 sql 查询操作,主库 master 默认可以不写
...
postgres:
- key: node1 # 数据节点
...
  • 注解 ​Sharding切换数据源,组内节点默认随机选择(查从写主)
@Mapper
@Sharding("mysql")
public interface UserMapper extends BaseMapper<User> {
@Sharding("postgres")
Long selectByUsername(String username);
}
  • 切换指定数据库节点
// 切换到 mysql 从库 node2 节点
ShardingKey.change("mysqlnode2");

多数据源动态加载卸载

mybatis-mate-sharding-dynamic

多数据源事务( jta atomikos)

mybatis-mate-sharding-jta-atomikos