Activiti 開發案例之 API 映射 SQL 查詢

前言

Activiti 自身提供了一套用戶管理,但是在開發中業務系統本身就有一套用戶管理系統,這時候就要把業務系統中的部分用戶數據同步到 Activiti 用戶表管理中。那麼,如果不同步呢?不少開發者一開始以爲必須要有用戶纔可以運行,其實 Task 的 Assignee,Candidate Users,Candidate Groups 信息已經以字符串形式保存在 act_ru_tak 和 ACT_RU_IDENTITYLINK 表中。只有少部分的查詢 API 會用到 ACT_ID_* 表中的數據進行關聯查詢。

環境

軟件 版本
SpringBoot 1.5.10
activiti-spring-boot-starter-basic 6.0

查詢

taskAssignee

按照指派人查詢,直接查詢表 ACT_RU_TASK。

API:

taskService.createTaskQuery().taskAssignee(userId);

SQL:

select distinct RES.* from ACT_RU_TASK RES WHERE RES.ASSIGNEE_ = ?

taskCandidateGroup

按照分配組查詢,沒有用到 ACT_ID_* 表的數據。

API:

taskService.createTaskQuery().taskCandidateGroup("部門經理");

SQL:

SELECT DISTINCT
  RES.*
FROM ACT_RU_TASK RES
  INNER JOIN ACT_RU_IDENTITYLINK I
    ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
    AND I.TYPE_ = 'candidate'
    AND (I.GROUP_ID_ IN(?))

taskCandidateGroupIn

按照分配組查詢,沒有用到 ACT_ID_*表的數據。

API:

List<String> candidateGroups = new ArrayList<String>();
candidateGroups.add("部門經理");
candidateGroups.add("總裁");
taskService.createTaskQuery().taskCandidateGroupIn (candidateGroups);

SQL:

SELECT DISTINCT
  RES.*
FROM ACT_RU_TASK RES
  INNER JOIN ACT_RU_IDENTITYLINK I
    ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
    AND I.TYPE_ = 'candidate'
    AND (I.GROUP_ID_ IN(?))

taskCandidateOrAssigned

按照分配組 OR 指派人查詢,用到了 ACT_ID_*表的數據,傳入userId查詢其所在權限組。

API:

taskService.createTaskQuery().taskCandidateOrAssigned(userId);

SQL:

首先查詢用戶所在組權限

SELECT
  g.*
FROM ACT_ID_GROUP g,
  ACT_ID_MEMBERSHIP membership
WHERE g.ID_ = membership.GROUP_ID_
    AND membership.USER_ID_ = ?

 

然後查詢指派人任務或者指派人爲空並且用戶所在權限組的任務

SELECT DISTINCT
  RES.*
FROM ACT_RU_TASK RES
  LEFT JOIN ACT_RU_IDENTITYLINK I
    ON I.TASK_ID_ = RES.ID_
WHERE (RES.ASSIGNEE_ = ?
        OR (RES.ASSIGNEE_ IS NULL
            AND (I.USER_ID_ = ?
                  OR I.GROUP_ID_ IN(SELECT
                                      g.GROUP_ID_
                                    FROM ACT_ID_MEMBERSHIP g
                                    WHERE g.USER_ID_ = ?))))

taskCandidateUser

API:

taskService.createTaskQuery().taskCandidateUser(userId);
  • 先查找用戶所屬的組(用戶所屬用戶組的信息從 Activiti 的 ACT_ID_*表獲取)
SELECT
  g.*
FROM ACT_ID_GROUP g,
  ACT_ID_MEMBERSHIP membership
WHERE g.ID_ = membership.GROUP_ID_
    AND membership.USER_ID_ = ?
  • 如果找到了用戶組信息
SELECT DISTINCT
  RES.*
FROM ACT_RU_TASK RES
  INNER JOIN ACT_RU_IDENTITYLINK I
    ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
    AND I.TYPE_ = 'candidate'
    AND (I.USER_ID_ = ?
          OR I.GROUP_ID_ IN(?))
  • 如果找不到用戶所屬的組
SELECT DISTINCT
  RES.*
FROM ACT_RU_TASK RES
  INNER JOIN ACT_RU_IDENTITYLINK I
    ON I.TASK_ID_ = RES.ID_
WHERE RES.ASSIGNEE_ IS NULL
    AND I.TYPE_ = 'candidate'
    AND (I.USER_ID_ = ?)

按照所屬人查詢 taskOwner

API:

taskService.createTaskQuery().taskOwner(userId);

SQL:

SELECT DISTINCT
  RES.*
FROM ACT_RU_TASK RES
WHERE RES.OWNER_ = ?

日誌

在 logback.xml 追加以下配置,就可以輸出 Activiti 查詢語句。

<!-- Activiti日誌 -->
<logger name="org.activiti" level="INFO" />
<logger name="org.activiti.engine.impl.persistence.entity" level="DEBUG" />

說明

有些查詢使用到 Activiti 自帶的用戶信息的,比如 taskCandidateOrAssigned,如果項目中使用了自己的權限系統,這些 API 是不靈光的,這裏提供三種方案,僅供參考:

  • 同步系統用戶權限信息到 Activiti 自帶用戶組,不推薦。

  • 修改源代碼 Task.xml 中的查詢SQL,把 Activiti 自帶的用戶表替換成業務系統用戶表,不推薦。

  • 用視圖覆蓋同名的ACT_ID_系列表,創建的視圖要保證數據類型,推薦。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章