成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Spring Boot + MyBatis-Plus 數據權限管理入門技術方案

開發 前端
通過注解驅動的方式實現靈活的數據權限控制,可根據實際業務需求擴展權限類型和過濾規則。建議結合具體業務場景調整數據權限模型和SQL生成策略。?

一、需求分析

實現不同用戶/角色在訪問同一數據接口時,根據預設規則動態過濾數據。例如:

  • 普通用戶只能查看自己創建的數據
  • 部門管理員可查看本部門所有數據
  • 超級管理員可查看全部數據

二、技術選型

  • Spring Boot 3.x:基礎框架
  • MyBatis-Plus 3.5+:數據訪問層增強
  • Sa-Token/Spring Security:權限認證(可選)
  • Jackson:JSON處理
  • MySQL:數據庫

三、核心設計

3.1 數據權限模型

@Data
public class DataScope {
    // 權限類型:ALL, DEPT, SELF, CUSTOM
    private String scopeType;
    // 可見部門ID集合
    private Set<Long> deptIds;
    // 用戶ID
    private Long userId;
    // 自定義SQL條件
    private String customCondition;
}

3.2 實現方案

通過MyBatis-Plus的攔截器機制動態修改SQL,結合自定義注解實現聲明式數據權限控制。

圖片圖片

四、實現步驟

4.1 添加依賴(pom.xml)

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.5.3.1</version>
</dependency>

4.2 定義數據權限注解

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface DataPermission {
    /**
     * 部門表別名(多表關聯時使用)
     */
    String deptAlias() default "";


    /**
     * 用戶ID字段名(默認create_by)
     */
    String userColumn() default "create_by";


    /**
     * 部門ID字段名(默認dept_id)
     */
    String deptColumn() default "dept_id";
}

4.3 實現數據權限攔截器

@Intercepts({
    @Signature(type = Executor.class, method = "prepare", args = {Connection.class, Integer.class})
})
public class DataPermissionInterceptor implements Interceptor {


    @Override
    public Object intercept(Invocation invocation) throws Throwable {
        // 獲取當前用戶數據權限
        DataScope dataScope = SecurityUtils.getDataScope();


        if (dataScope == null || dataScope.isAllAccess()) {
            return invocation.proceed();
        }


        StatementHandler handler = (StatementHandler) invocation.getTarget();
        MetaObject metaObject = SystemMetaObject.forObject(handler);
        MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");


        // 獲取注解信息
        DataPermission dataPermission = getDataPermissionAnnotation(mappedStatement);


        if (dataPermission != null) {
            BoundSql boundSql = handler.getBoundSql();
            String originalSql = boundSql.getSql();
            String newSql = buildDataScopeSql(originalSql, dataScope, dataPermission);
            metaObject.setValue("delegate.boundSql.sql", newSql);
        }


        return invocation.proceed();
    }


    private String buildDataScopeSql(String originalSql, DataScope dataScope, DataPermission annotation) {
        StringBuilder where = new StringBuilder();


        switch (dataScope.getScopeType()) {
            case "DEPT":
                where.append(annotation.deptColumn())
                     .append(" IN (")
                     .append(StringUtils.join(dataScope.getDeptIds(), ","))
                     .append(")");
                break;
            case "SELF":
                where.append(annotation.userColumn())
                     .append(" = ")
                     .append(dataScope.getUserId());
                break;
            case "CUSTOM":
                where.append(dataScope.getCustomCondition());
                break;
        }


        if (originalSql.toUpperCase().contains("WHERE")) {
            return originalSql + " AND " + where;
        } else {
            return originalSql + " WHERE " + where;
        }
    }
}

4.4 注冊攔截器

@Configuration
public class MybatisPlusConfig {


    @Bean
    public DataPermissionInterceptor dataPermissionInterceptor() {
        return new DataPermissionInterceptor();
    }
}

4.5 Service層應用

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> {


    @DataPermission(deptColumn = "order_dept_id")
    public Page<Order> listOrders(Page<Order> page) {
        return baseMapper.selectPage(page, null);
    }
}

五、初步數據表設計

CREATE TABLE sys_user (
    id BIGINT PRIMARY KEY,
    username VARCHAR(50),
    dept_id BIGINT
);


CREATE TABLE sys_order (
    id BIGINT PRIMARY KEY,
    order_no VARCHAR(50),
    create_by BIGINT COMMENT '創建人ID',
    order_dept_id BIGINT COMMENT '訂單所屬部門'
);

六、擴展優化

  1. 多表關聯處理:通過注解的deptAlias指定表別名
  2. 緩存優化:緩存用戶權限數據,避免頻繁查詢
  3. 租戶隔離:結合多租戶方案實現更復雜場景
  4. 性能監控:記錄SQL修改日志用于審計

七、測試驗證

@Test
void testDataPermission() {
    // 模擬普通用戶登錄
    loginUser("user1", "DEPT", Set.of(1001L));


    List<Order> orders = orderService.listOrders();
    assertThat(orders).allMatch(order -> order.getOrderDeptId() == 1001);


    // 模擬管理員登錄
    loginUser("admin", "ALL", null);
    orders = orderService.listOrders();
    assertThat(orders).hasSize(100);
}

八、注意事項

  1. SQL注入防護:嚴格校驗自定義條件表達式
  2. 索引優化:確保添加的過濾條件字段有合適索引
  3. 事務處理:在事務邊界內保持數據權限一致性
  4. 性能影響:避免過度復雜的權限條件影響查詢性能

該方案通過注解驅動的方式實現靈活的數據權限控制,可根據實際業務需求擴展權限類型和過濾規則。建議結合具體業務場景調整數據權限模型和SQL生成策略。

責任編輯:武曉燕 來源: 小編程聊林
相關推薦

2024-07-31 09:56:20

2011-04-13 09:53:20

2024-12-20 16:49:15

MyBatis開發代碼

2023-12-13 12:20:36

SpringMySQL數據源

2023-06-07 08:08:37

MybatisSpringBoot

2023-03-13 07:35:44

MyBatis分庫分表

2021-01-05 05:36:39

設計Spring Boot填充

2025-02-27 09:45:47

2024-09-02 08:12:32

Spring策略MyBatis

2023-06-14 08:34:18

Mybatis死鎖框架

2023-07-29 22:02:06

MyBatis數據庫配置

2023-10-31 08:01:48

Mybatis參數jdbcurl?

2023-06-07 08:00:00

MySQL批量插入

2025-02-13 07:59:13

2009-09-23 11:37:31

Hibernate S

2011-02-24 15:04:00

PostgreSQL數據庫psql

2011-03-24 14:40:29

PostgreSQL數管理

2024-02-28 09:35:52

2024-11-28 19:03:56

2020-12-31 07:55:33

spring bootMybatis數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品粉嫩aⅴ一区二区三区四区 | 午夜精品一区 | 亚洲 中文 欧美 日韩 在线观看 | 欧美日韩精品中文字幕 | 伊人一区 | 日韩在线观看精品 | 美女国产精品 | 精品乱码一区二区三四区视频 | 午夜免费视频观看 | 日韩精品一区中文字幕 | 美女天堂 | 天堂在线1| 欧美极品在线观看 | 亚洲一区视频 | 老头搡老女人毛片视频在线看 | 欧美专区日韩专区 | www.中文字幕.com | 人成精品| 成人一区在线观看 | 中文在线一区二区 | 国产亚洲精品久久情网 | 操操操操操| 人人亚洲| 久久精品视频网站 | 欧美小视频在线观看 | 欧美视频免费在线观看 | 国产免费又色又爽又黄在线观看 | av在线黄 | 中文久久 | 国产精品视频网 | 日日夜夜精品视频 | 韩国av一区二区 | 涩涩视频网站在线观看 | 在线一区视频 | 精品国产乱码久久久久久图片 | 亚洲精品视频在线观看免费 | 青青草精品视频 | 午夜三区| 午夜国产羞羞视频免费网站 | 国产ts一区 | 日本精品视频一区二区 |