mirror of
https://gitee.com/mybatis-flex/mybatis-flex.git
synced 2025-12-07 00:58:24 +08:00
Merge branch 'main' of https://gitee.com/mybatis-flex/mybatis-flex
This commit is contained in:
commit
f811c56a24
@ -49,7 +49,7 @@ MaskManager.registerMaskProcesser("自定义规则名称"
|
||||
```
|
||||
|
||||
2、使用自定义的脱敏规则
|
||||
```java 7
|
||||
```java
|
||||
@Table("tb_account")
|
||||
public class Account {
|
||||
|
||||
@ -66,19 +66,47 @@ public class Account {
|
||||
在某些场景下,程序希望查询得到的数据是原始数据,而非脱敏数据。比如要去查询用户的手机号,然后给用户发送短信。又或者说,我们进入编辑页面编辑用户数据,
|
||||
如果编辑页面展示的是脱敏数据,然后再次点击保存,那么数据库的真实数据也会被脱敏覆盖。
|
||||
|
||||
因此,MaskManager 提供了 `skipMask`、`restoreMask` 两个方法来处理这种场景:
|
||||
因此,MaskManager 提供了 `withoutMask`、`skipMask`、`restoreMask` 三个方法来处理这种场景:
|
||||
|
||||
```java 2,7
|
||||
推荐使用`withoutMask`方法,该方法使用了模版方法设计模式,保障跳过脱敏处理并执行相关逻辑后自动恢复脱敏处理。
|
||||
|
||||
`withoutMask`方法实现如下:
|
||||
|
||||
```java
|
||||
public static <T> T withoutMask(Supplier<T> supplier) {
|
||||
try {
|
||||
skipMask();
|
||||
return supplier.get();
|
||||
} finally {
|
||||
restoreMask();
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
使用方法:
|
||||
|
||||
```java
|
||||
AccountMapper mapper = ...;
|
||||
List<Account> accounts = MaskManager.withoutMask(mapper::selectAll);
|
||||
System.out.println(accounts);
|
||||
```
|
||||
|
||||
`skipMask`和`restoreMask`方法需配套使用,推荐使用`try{...}finally{...}`模式,如下例所示。
|
||||
使用这两个方法可以自主控制跳过脱敏处理和恢复脱敏处理的时机。
|
||||
当跳过脱敏处理和恢复脱敏处理无法放在同一个方法中时,可以使用这两个方法。
|
||||
此时需要仔细处理代码分支及异常,以防止跳过脱敏处理后未恢复脱敏处理,导致安全隐患。
|
||||
|
||||
```java
|
||||
try {
|
||||
MaskManager.skipMask()
|
||||
MaskManager.skipMask();
|
||||
|
||||
//此处查询到的数据不会进行脱敏处理
|
||||
accountMapper.selectListByQuery(...)
|
||||
accountMapper.selectListByQuery(...);
|
||||
} finally {
|
||||
MaskManager.restoreMask()
|
||||
MaskManager.restoreMask();
|
||||
}
|
||||
```
|
||||
|
||||
::: tip 提示
|
||||
在具体的应用中,我们通常会把 `skipMask()` 和 `restoreMask()` 放到统一的拦截器里,对某一类业务进行统一拦截和处理。
|
||||
在具体的应用中,我们通常会把`withoutMask`、`skipMask()` 和 `restoreMask()` 放到统一的拦截器里,对某一类业务进行统一拦截和处理。
|
||||
:::
|
||||
|
||||
@ -111,16 +111,42 @@ DELETE FROM tb_article where id = ? and tenant_id in (?, ?, ?)
|
||||
|
||||
### 忽略租户条件
|
||||
|
||||
在某些场景下,在增删改查等操作,我们可能需要忽略租户条件,此时可以使用如下代码:
|
||||
在某些场景下,在增删改查等操作,我们可能需要忽略租户条件,
|
||||
此时可以使用TenantManager的`withoutTenantCondition`、`ignoreTenantCondition`、`restoreTenantCondition`三个方法。
|
||||
|
||||
推荐使用`withoutTenantCondition`方法,该方法使用了模版方法设计模式,保障忽略 tenant 条件并执行相关逻辑后自动恢复 tenant 条件。
|
||||
|
||||
`withoutTenantCondition`方法实现如下:
|
||||
```java
|
||||
public static <T> T withoutTenantCondition(Supplier<T> supplier) {
|
||||
try {
|
||||
ignoreTenantCondition();
|
||||
return supplier.get();
|
||||
} finally {
|
||||
restoreTenantCondition();
|
||||
}
|
||||
}
|
||||
```
|
||||
使用方法:
|
||||
```java
|
||||
TenantAccountMapper mapper = ...;
|
||||
List<TenantAccount> tenantAccounts = TenantManager.withoutTenantCondition(mapper::selectAll);
|
||||
System.out.println(tenantAccounts);
|
||||
```
|
||||
|
||||
`ignoreTenantCondition`和`restoreTenantCondition`方法需配套使用,推荐使用`try{...}finally{...}`模式,如下例所示。
|
||||
使用这两个方法可以自主控制忽略 tenant 条件和恢复 tenant 条件的时机。
|
||||
当忽略 tenant 条件和恢复 tenant 条件无法放在同一个方法中时,可以使用这两个方法。
|
||||
此时需要仔细处理代码分支及异常,以防止忽略 tenant 条件后未恢复 tenant 条件,导致数据异常。
|
||||
|
||||
```java
|
||||
try {
|
||||
TenantManager.ignoreTenantCondition()
|
||||
TenantManager.ignoreTenantCondition();
|
||||
|
||||
//此处操作的数据不会带有 tenant_id 的条件
|
||||
accountMapper.selectListByQuery(...)
|
||||
accountMapper.selectListByQuery(...);
|
||||
} finally {
|
||||
TenantManager.restoreTenantCondition()
|
||||
TenantManager.restoreTenantCondition();
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@ package com.mybatisflex.core.mask;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* 数据脱敏工厂类
|
||||
@ -56,6 +57,18 @@ public class MaskManager {
|
||||
|
||||
private static ThreadLocal<Boolean> skipFlags = new ThreadLocal<>();
|
||||
|
||||
/**
|
||||
* 跳过脱敏处理
|
||||
*/
|
||||
public static <T> T withoutMask(Supplier<T> supplier) {
|
||||
try {
|
||||
skipMask();
|
||||
return supplier.get();
|
||||
} finally {
|
||||
restoreMask();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 跳过脱敏处理
|
||||
*/
|
||||
|
||||
@ -15,6 +15,8 @@
|
||||
*/
|
||||
package com.mybatisflex.core.tenant;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class TenantManager {
|
||||
|
||||
private static ThreadLocal<Boolean> ignoreFlags = new ThreadLocal<>();
|
||||
@ -29,6 +31,18 @@ public class TenantManager {
|
||||
TenantManager.tenantFactory = tenantFactory;
|
||||
}
|
||||
|
||||
/**
|
||||
* 忽略 tenant 条件
|
||||
*/
|
||||
public static <T> T withoutTenantCondition(Supplier<T> supplier) {
|
||||
try {
|
||||
ignoreTenantCondition();
|
||||
return supplier.get();
|
||||
} finally {
|
||||
restoreTenantCondition();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 忽略 tenant 条件
|
||||
|
||||
@ -0,0 +1,33 @@
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
import com.mybatisflex.core.mask.MaskManager;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.List;
|
||||
|
||||
public class MaskManagerTest {
|
||||
|
||||
public static void main(String[] args) {
|
||||
DataSource dataSource = new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.H2)
|
||||
.setName("db1")
|
||||
.addScript("schema.sql")
|
||||
.addScript("data.sql")
|
||||
.build();
|
||||
|
||||
MybatisFlexBootstrap.getInstance()
|
||||
.setDataSource(dataSource)
|
||||
.addMapper(AccountMapper.class)
|
||||
.start();
|
||||
|
||||
//获取 mapper
|
||||
AccountMapper mapper = MybatisFlexBootstrap.getInstance().getMapper(AccountMapper.class);
|
||||
List<Account> accounts = mapper.selectAll();
|
||||
// List<Account> accounts = MaskManager.withoutMask(mapper::selectAll);
|
||||
System.out.println(accounts);
|
||||
}
|
||||
|
||||
}
|
||||
@ -59,4 +59,15 @@ public class TenantAccount{
|
||||
public void setTenantId(Long tenantId) {
|
||||
this.tenantId = tenantId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TenantAccount{" +
|
||||
"id=" + id +
|
||||
", userName='" + userName + '\'' +
|
||||
", age=" + age +
|
||||
", birthday=" + birthday +
|
||||
", tenantId=" + tenantId +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
|
||||
@ -0,0 +1,46 @@
|
||||
package com.mybatisflex.test;
|
||||
|
||||
import com.mybatisflex.core.MybatisFlexBootstrap;
|
||||
import com.mybatisflex.core.audit.AuditManager;
|
||||
import com.mybatisflex.core.audit.ConsoleMessageCollector;
|
||||
import com.mybatisflex.core.tenant.TenantFactory;
|
||||
import com.mybatisflex.core.tenant.TenantManager;
|
||||
import com.mybatisflex.mapper.TenantAccountMapper;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
|
||||
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
|
||||
|
||||
import javax.sql.DataSource;
|
||||
import java.util.List;
|
||||
|
||||
public class TenantManagerTester {
|
||||
|
||||
public static void main(String[] args) {
|
||||
DataSource dataSource = new EmbeddedDatabaseBuilder()
|
||||
.setType(EmbeddedDatabaseType.H2)
|
||||
.addScript("schema03.sql")
|
||||
.addScript("data03.sql")
|
||||
.build();
|
||||
|
||||
MybatisFlexBootstrap.getInstance()
|
||||
.setDataSource(dataSource)
|
||||
.addMapper(TenantAccountMapper.class)
|
||||
.start();
|
||||
|
||||
//输出日志
|
||||
AuditManager.setAuditEnable(true);
|
||||
AuditManager.setMessageCollector(new ConsoleMessageCollector());
|
||||
|
||||
//配置 tenantFactory
|
||||
TenantManager.setTenantFactory(new TenantFactory() {
|
||||
@Override
|
||||
public Object[] getTenantIds() {
|
||||
return new Object[]{1};
|
||||
}
|
||||
});
|
||||
|
||||
TenantAccountMapper mapper = MybatisFlexBootstrap.getInstance().getMapper(TenantAccountMapper.class);
|
||||
List<TenantAccount> tenantAccounts = TenantManager.withoutTenantCondition(mapper::selectAll);
|
||||
System.out.println(tenantAccounts);
|
||||
}
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user