文档章节

Activiti中彻底解决待办事项列表查询复杂、API不友好的设计方案

李玉珏
 李玉珏
发布于 2015/04/07 17:12
字数 1341
阅读 15128
收藏 15

       我们使用工作流引擎,一个非常重要的功能就是获取待办事项列表,在Activiti中,我们可以通过TaskService的相关API进行查询,这些API设计优雅,但是实际使用中往往不够方便,也缺乏灵活性,达不到技术解决方案的要求,主要有如下几个问题:

1.多数情况无法通过调用一个API满足需求,这时一个现实问题就是需要对结果集进行合并然后排序,这样就显得比较麻烦;

2.和项目业务表关联困难;

3.Activiti中相关查询返回的是Activiti定义的实体,这些实体包含的信息可能不够;

4.Activiti中的实体,可能和项目中的对象关系映射(ORM)冲突;

        鉴于上述原因,在一些大规模的项目中,Activiti提供的查询API,实际使用价值不大,我们需要另外寻找解决方案。在Activiti的查询API中,也提供原始SQL的查询接口,但是大量使用后,会发现代码不够优雅,维护困难。这个问题其实从开发者角度,查询时用用户的id,用最简单的SQL查询出来所有想要的信息是最理想的。

        分析上述缺点和需求后,我们认为通过API方式进行查询的话,总是有各种缺陷,因此把目标放在数据库上,如果能通过定义视图的方式解决问题,那么将彻底解决查询的方便性、灵活性、通用性问题。

        经过分析Activiti的数据库表,我们发现并不复杂,和待办事项有关系的表,包括ACT_RU_TASK、ACT_RU_IDENTITYLINK,ACT_RU_TASK中存储了任务相关信息,ACT_RU_IDENTITYLINK中存储了候选组和候选人信息,这里面一个比较重要的问题就是,Activiti中的候选组、候选人如何跟系统中的用户、组织、角色对应的问题,本文提供的解决方案,假定系统中有一张名为SYS_ROLE_USER的表,该表中存储了角色和用户的对应关系,并且Activiti中的候选组和角色是同一个概念,开发者的系统中具体是什么情况,需要开发者举一反三,本文仅提供一个设计思路。

        在Activiti中,对于一个节点,可分为受托人,候选人和候选组三种情况,后两种可以设置多个,用逗号分隔,对应到数据库中,会被拆分为ACT_RU_IDENTITYLINK的多条记录,这些我们都需要考虑,细节上可以通过UNION实现,下面是样例代码,该代码基于Oracle数据库,其他数据库的版本,稍后会说明。

CREATE VIEW V_TASKLIST AS
SELECT A.ID_ AS TASK_ID,
       A.PROC_INST_ID_ PROC_INST_ID,
       A.TASK_DEF_KEY_ AS ACT_ID,
       A.NAME_ AS ACT_NAME,
       A.ASSIGNEE_ AS ASSIGNEE,
       A.DELEGATION_ AS DELEGATION_ID,
       A.DESCRIPTION_ AS DESCRIPTION,
       TO_CHAR(A.CREATE_TIME_, 'YYYY-MM-DD HH24:MI:SS') AS CREATE_TIME,
       TO_CHAR(A.DUE_DATE_,'YYYY-MM-DD HH24:MI:SS') AS DUE_DATE,
       I.USER_ID CANDIDATE
  FROM ACT_RU_TASK A
  LEFT JOIN (SELECT DISTINCT * FROM (SELECT TASK_ID_, TO_CHAR(USER_ID_) USER_ID
                    FROM ACT_RU_IDENTITYLINK I, ACT_RU_TASK T
                      WHERE TASK_ID_ IS NOT NULL
                        AND USER_ID_ IS NOT NULL
                        AND I.TASK_ID_ = T.ID_
                        AND T.ASSIGNEE_ IS NULL
                        AND TYPE_ = 'candidate'
                     UNION
                     SELECT TASK_ID_, R.USER_ID
                       FROM ACT_RU_IDENTITYLINK I,SYS_ROLE_USER R,ACT_RU_TASK T
                      WHERE I.TASK_ID_ IS NOT NULL
                        AND I.GROUP_ID_ IS NOT NULL
                        AND I.TASK_ID_ = T.ID_
                        AND T.ASSIGNEE_ IS NULL
                        AND TYPE_ = 'candidate'
                        AND I.GROUP_ID_ = R.ROLE_ID)U) I--候选组和业务上的角色用户表关联
    ON A.ID_ = I.TASK_ID_

        这个视图比较简单,主要查询了任务信息,如果还需要其他信息,比如和流程实例、流程定义等,可以自行增加其他的表关联,比如要和业务表关联需要一个很重要的字段就是BUSINESS_KEY_,这个和ACT_RU_EXECUTION表关联即可。

        这个视图定义好之后,代办查询可以用如下的更简洁的SQL实现:

SELECT * FROM V_TASKLIST WHERE ASSIGNEE = :userId OR CANDIDATE = :userId

        这样的话,和业务表关联也非常的方便,也不会受到API的限制,也不涉及和系统的ORM兼容的问题,基本上想查询什么信息就能用一个简单的SQL查询到什么信息,基本可以作为一个通用的解决方案了。

        上述例子仅提供了Oracle的代码,对于兼容多数据库的设计,比较麻烦,各种数据库都对视图的创建做了较多的限制,比如SQLServer不能在SQL中写ORDER BY,MySQL中FROM字句不能嵌套子查询,以及不同数据库字段类型定义不同等,在我们的解决方案中,基本上就是把上述SQL做了拆分,定义了若干非常小的视图,然后V_TASKLIST视图再查询这些视图。具体上开发者可以灵活处理,本文不再展开。

© 著作权归作者所有

共有 人打赏支持
李玉珏

李玉珏

粉丝 298
博文 63
码字总数 106838
作品 0
沈阳
技术主管
私信 提问
加载中

评论(3)

d
dizh
学习了~
李玉珏
李玉珏

引用来自“启明89”的评论

感谢大神的分享,这个视图非常好,我还想请教一下在TaskListener实现类的notify方法中如何获取当前登录用户的信息呢?

我们登录用户信息是放到线程局部变量中的
启明89
感谢大神的分享,这个视图非常好,我还想请教一下在TaskListener实现类的notify方法中如何获取当前登录用户的信息呢?
zhaoml529/SpringMVC-Activiti5.16-Shiro

SpringOA简介 基于SpringMVC+Shiro+Activiti 5.16 的简单OA,可以快速入门Activiti学习用。 此版本前台使用的是EasyUI 框架简介 框架以Spring Framework为核心、Spring MVC作为模型视图控制器...

zhaoml529
2017/05/19
0
0
单独部署activiti服务,引擎数据获取的问题

@咖啡兔 你好,想跟你请教个问题:我了解到activiti-rest模块是支持单独部署,调用引擎的。但是假如有这样的应用场景:我的用户角色不是存在activiti的表里的,而是存在另外的地方,现在我想...

詹妮花
2017/06/15
126
0
activiti5 用户数据迁移

@咖啡兔 你好,想跟你请教个问题:之前我们用Activiti已经在用户那里生成了一些待办事项、现在由于业务流程有改动、我们想在新的业务流程中保留用户的代办事项、想请教一下有没有这方面的经验...

jerric
2013/04/10
523
2
aspx页面集成工作流引擎api

最近用户在做工作流系统的集成时,总会要求快速的集成到用户的应用系统。 一般一个成熟的工作流软件产品,会有流程设计器,流程引擎,表单设计器,流程管理中心。在流程管理中心能可视化给业...

长平狐
2012/10/11
94
0
Activiti 5.11 发布,业务流程管理

1. 圣诞大礼包 这是我第一次为Activiti的发布撰文,因为这次的发布我觉得很有必要和大家分享,这其中包含了我期待的新特性和已知问题的修复;而且还有一个重量级的模块Activiti Modeler。 在...

咖啡兔
2012/12/06
5.4K
15

没有更多内容

加载失败,请刷新页面

加载更多

防止Tweak

什么是tweak? 英文意思为捏, 拧,扭,稍稍调整(机器、系统等)。 依据维基百科的定义,tweak指的是对电子系统进行轻微调整来增强其功能的工具;在ios中tweak特指那些能够增强其它可执行程...

HeroHY
19分钟前
0
0
linux中常用标识---不定期更新

LINUX常用标识符: 1 & && | || &: 表示进程在后台运行 例如 redis-server & 不是所有后台运行都是& 比如es ./bin/elasticsearch -d es后台运行&&: 第一个命令执行成功后 才执行后面的命令...

geek土拨鼠
57分钟前
1
0
Mybatis 中$与#的区别,预防SQL注入

一直没注意Mybatis 中$与#的区别,当然也是更习惯使用#,没想到避免了SQL注入,但是由于要处理项目中安全渗透的问题,不可避免的又遇到了这个问题,特此记录一下。 首先是共同点: 在mybatis...

大雁南飞了
今天
0
0
Spring Clould负载均衡重要组件:Ribbon中重要类的用法

Ribbon是Spring Cloud Netflix全家桶中负责负载均衡的组件,它是一组类库的集合。通过Ribbon,程序员能在不涉及到具体实现细节的基础上“透明”地用到负载均衡,而不必在项目里过多地编写实现...

Ala6
今天
0
0
让 linux 删除能够进入回收站

可以参考这个贴子 https://blog.csdn.net/F8qG7f9YD02Pe/article/details/79543316 从那个git地址 把saferm.sh下载下来 把saferm.sh复制到 /usr/bin 目录下 在用~/目下 的.bashrc 下加一句这...

shzwork
今天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部