在刚接触流程引擎Activiti的时候误以为必须得使用它所提供的用户管理,而一般来说在业务系统里本身就自带了一套用户管理,于是就去寻找同步用户数据到Activiti的ACT_ID_*
表中方法,找到了这篇文章。
但是在后面的使用过程中发现Activiti完全可以在没有用户信息的情况下运行,我们可以指派ACT_ID_*
表中根本不存在的用户或组给一个Task,然后使用TaskService
查询这个Task。可以看Activiti论坛的这个回答。
经过观察后发现,Task的Assignee,Candidate Users,Candidate Groups信息只是以字符串形式保存在act_ru_tak
和ACT_RU_IDENTITYLINK
表中,更进一步证实了我的想法。
不过事情有一些例外,Activiti实际上在查询Task的时候,在某些情况下还是使用了ACT_ID_*
表中的数据,下面总结了出来。
taskCandidateOrAssigned
taskService.createTaskQuery().taskCandidateOrAssigned(userId);
当使用taskCandidateOrAssigned
做查询条件时,Activiti会按照以下规则查找Task:
Assignee匹配
或者*.bpmn中定义的Candidate Users 匹配
或者Candidate Group 匹配(用户所属用户组的信息从Activiti的
ACT_ID_*
表获取)
可以从以下SQL看出它查找的逻辑:
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_ = ?
)
)
)
)
taskAssignee
taskService.createTaskQuery().taskAssignee(userId);
当使用taskAssignee
做查询条件时,Activiti会按照以下规则查找Task:
-
Assignee匹配。可以从以下SQL看出它查找的逻辑:
select distinct RES.* from ACT_RU_TASK RES WHERE RES.ASSIGNEE_ = ?
taskCandidateGroup
taskService.createTaskQuery().taskCandidateGroup(userId);
当使用taskCandidateGroup
做查询条件时,Activiti会按照以下规则查找Task:
-
*.bpmn中定义的Candidate Groups匹配。可以从以下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 ( ? ) )
taskCandidateUser
taskService.createTaskQuery().taskCandidateUser(userId);
当使用taskCandidateUser
做查询条件时,Activiti会按照以下规则查找Task:
-
先查找用户所属的组(用户所属用户组的信息从Activiti的
ACT_ID_*
表获取)select g.* from ACT_ID_GROUP g, ACT_ID_MEMBERSHIP membership where g.ID_ = membership.GROUP_ID_ and membership.USER_ID_ = ?
-
如果找到了用户组信息,那么
*.bpmn中定义的Candidate Users 匹配
-
或者Candidate Group 匹配(用户所属用户组的信息从Activiti的
ACT_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 ( ? , ? ) )
-
如果找不到用户所属的组,那么和*.bpmn中定义的Candidate Users 匹配
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_ = ? )
taskCandidateGroupIn
taskService.createTaskQuery().taskCandidateGroupIn(groups);
当使用taskOwner
做查询条件时,Activiti会按照以下规则查找Task:
-
*.bpmn中定义的Candidate Groups匹配(匹配一个就行)。可以从以下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 ( ? , ? ) )
taskOwner
taskService.createTaskQuery().taskOwner(userId);
当使用taskOwner
做查询条件时,Activiti会按照以下规则查找Task:
-
*.bpmn中定义的owner匹配。可以从以下SQL看出它查找的逻辑:
select distinct RES.* from ACT_RU_TASK RES WHERE RES.OWNER_ = ?
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。