成人免费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生成策略。

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

2011-04-13 09:53:20

2024-07-31 09:56:20

2024-12-20 16:49:15

MyBatis開發代碼

2023-12-13 12:20:36

SpringMySQL數據源

2023-06-07 08:08:37

MybatisSpringBoot

2021-01-05 05:36:39

設計Spring Boot填充

2023-03-13 07:35:44

MyBatis分庫分表

2025-02-27 09:45:47

2023-07-29 22:02:06

MyBatis數據庫配置

2023-06-14 08:34:18

Mybatis死鎖框架

2024-09-02 08:12:32

Spring策略MyBatis

2025-02-13 07:59:13

2023-06-07 08:00:00

MySQL批量插入

2023-10-31 08:01:48

Mybatis參數jdbcurl?

2009-09-23 11:37:31

Hibernate S

2011-02-24 15:04:00

PostgreSQL數據庫psql

2011-03-24 14:40:29

PostgreSQL數管理

2024-11-28 19:03:56

2024-02-28 09:35:52

2023-01-12 09:13:49

Mybatis數據庫
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日本一区二区高清不卡 | 草草网| 在线日韩精品视频 | 久久精品国产一区 | 色视频一区二区 | 日本精品久久久久久久 | 91精品国产91久久久久久密臀 | 国产中文在线观看 | 成人午夜免费视频 | 成年人黄色小视频 | 欧美精品区 | 围产精品久久久久久久 | 成人欧美一区二区三区黑人孕妇 | 国产精品免费观看视频 | 中文字幕高清视频 | 久久久久久久久淑女av国产精品 | 在线观看视频一区二区三区 | 日韩视频在线免费观看 | 免费看片国产 | 日韩精品不卡 | 国产精品一区一区 | 欧美一区| 天天av综合 | av在线视 | 欧美精品一区三区 | 国产视频福利一区 | 麻豆久久久 | 免费观看www7722午夜电影 | 一区二区三区在线免费观看 | 91传媒在线观看 | 人人射人人插 | 一区二区三区四区五区在线视频 | 九九精品在线 | 麻豆va| 狠狠躁18三区二区一区 | 精品一区二区久久久久久久网站 | 久久久精品视 | 九九热在线免费视频 | 一区二区高清 | 国产精品成人品 | 国产激情视频网址 |