mybatis-flex/docs/zh/core/data-permission.md
bf109f 7da5dbbbef
update docs/zh/core/data-permission.md.
实例代码提交语言标识
2023-12-24 08:30:58 +00:00

136 lines
4.7 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 数据权限
数据权限指的是不同的用户,通过某一个方法去查询的时候,得到的是不同的数据结果集。常见的数据权限有:
- 获取全部数据
- 仅获取本人创建的数据
- 获取当前用户的部门数据
- 获取部门级以下部门的数据
- 获取某个地区的数据
- 等等
这一些,都是通过当前的用户的信息(部门、角色、权限等),查询时,添加特定的条件。在 MyBatis-Flex 中,我们可以通过 2 种方式来实现这一种需求。
## 方式1使用自定义数据方言 `IDialect`
在自定义方言中,重写 `forSelectByQuery` 方法,这个方法是用于构建返回根据 `QueryWrapper` 查询的方法, 以下是示例代码:
```java
public class MyPermissionDialect extends CommonsDialectImpl {
@Override
public String forSelectByQuery(QueryWrapper queryWrapper) {
//获取当前用户信息,为 queryWrapper 添加额外的条件
queryWrapper.and("...");
return super.buildSelectSql(queryWrapper);
}
}
```
特别的,如果您使用的是 `Oracle` 数据库,需要继承 `OracleDialect` 类,示例:
```java
public class MyOraclePermissionDialect extends OracleDialect {
// 这个构造器只有在 Oracle 12C 的版本下才需要添加。
// public MyOraclePermissionDialect() {
// super(LimitOffsetProcessor.DERBY);
// }
}
```
在项目启动时,通过 `DialectFactory` 注册 `MyPermissionDialect`
```java
DialectFactory.registerDialect(DbType.MYSQL,new MyPermissionDialect());
```
**常见问题1通过重写 `IDialect` 后,所有的查询都添加了条件,但是有些表不需要条件如何做?**
>答:可以通过 CPI 获取 QueryWrapper 查询了哪些表,然后进行动态处理。例如 `List<QueryTable> tables = CPI.getQueryTables(queryWrapper)`,然后进一步对
> `tables` 进行验证是否需要添加数据权限。
## 方式2重写 IService 的查询方法
在一般的应用中,查询是通过 Service 进行的MyBatis-Flex 提供了 `IService` 接口及其默认的 `ServiceImpl` 实现类。
我们可以通过构建自己的 `IServiceImpl` 来实现这一种需求,例如:
```java
public class MyServiceImpl<M extends BaseMapper<T>, T> implements IService<T> {
@Autowired
protected M mapper;
@Override
public BaseMapper<T> getMapper() {
return mapper;
}
@Override
public List<T> list(QueryWrapper query) {
//获取当前用户信息,为 queryWrapper 添加额外的条件
return IService.super.list(query);
}
}
```
当然,在 `IService` 中,除了 `list` 方法以外,还有其他的查询方法,可能也需要复写。
## 方式3使用自定义数据方言 `IDialect`
在自定义方言中,重写 `prepareAuth` 方法,根据自己的需求对 `QueryWrapper``sql`语句进行处理,添加额外条件, 以下是示例代码:
```java
public class AuthDialectImpl extends CommonsDialectImpl {
@Override
public void prepareAuth(QueryWrapper queryWrapper, OperateType operateType) {
List<QueryTable> queryTables = CPI.getQueryTables(queryWrapper);
if (queryTables == null || queryTables.isEmpty()) {
return;
}
for (QueryTable queryTable : queryTables) {
if (PROJECT.getTableName().equals(queryTable.getName())) {
queryWrapper.and(PROJECT.INSERT_USER_ID.eq(1));
}
}
super.prepareAuth(queryWrapper, operateType);
}
@Override
public void prepareAuth(String schema, String tableName, StringBuilder sql, OperateType operateType) {
if (PROJECT.getTableName().equals(tableName)) {
sql.append(AND).append(wrap("insert_user_id")).append(EQUALS).append(1);
}
super.prepareAuth(schema, tableName, sql, operateType);
}
@Override
public void prepareAuth(TableInfo tableInfo, StringBuilder sql, OperateType operateType) {
if (PROJECT.getTableName().equals(tableInfo.getTableName())) {
sql.append(AND).append(wrap("insert_user_id")).append(EQUALS).append(1);
}
super.prepareAuth(tableInfo, sql, operateType);
}
}
```
`QueryWrapper`的表做筛选可参考 **方式1**
在项目启动时通过 `DialectFactory` 注册 `AuthDialectImpl`以spring boot项目为例
```java
@Configuration
public class MybatisFlexConfig implements MyBatisFlexCustomizer {
@Override
public void customize(FlexGlobalConfig flexGlobalConfig) {
// 注册查询权限监听方言
DialectFactory.registerDialect(DbType.MYSQL, new AuthDialectImpl());
}
}
```
单元测试请参考源码中的`com.mybatisflex.coretest.AuthTest`