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

我们使用工作流引擎,一个非常重要的功能就是获取待办事项列表,在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视图再查询这些视图。具体上开发者可以灵活处理,本文不再展开。

时间: 2024-10-11 13:19:10

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

TaskPaper for Mac(纯文本待办事项列表)

TaskPaper for Mac特别版是一款非常实用的纯文本待办事项列表,软件类似系统自带的文本编辑器,具有快速的添加任务,大纲的功能.TaskPaper Mac可以帮助您创建项目列表及其任务,以便您始终了解需要执行的操作,重新组织列表,创建新项目,将项目标记为已完成以及删除已完成的项目非常简单. 彻底现代化.TaskPaper 3是全新的,同时保留了自2006年以来一直有效的原始纯文本基础. 主要特征 纯文本文件; 随处编辑类型和您的列表是自动格式化的组织项目:, - 任务,备注和@tags

jQuery模仿ToDoList实现简单的待办事项列表

功能:在文本框中输入待办事项按下回车后,事项会出现在未完成列表中:点击未完成事项前边的复选框后,该事项会出现在已完成列表中,反之亦然:点击删除按钮会删除该事项.待办事项的数据是保存到本地存储的(localStorage),就算关闭页面再打开,数据还是存在的(前提是要用相同浏览器). ToDoList链接:ToDoList—最简单的待办事项列表 先把css样式以及js文件引入进来,jQuery文件要写在你自己的js文件上边 <link rel="stylesheet" href=&

将sharepoint中的跨网站、列表查询的结果用SPGridView分页显示

将sharepoint中的跨网站.列表查询的结果用SPGridView分页显示 2008-12-30 10:14 by Virus-BeautyCode, 1200 阅读, 0 评论, 收藏, 编辑 我是用户控件(也就是ascx控件)写的查询界面和显示结果,然后用QuickPart包装了一下,这样做的好处就是复杂界面可以使用拖动控件来开发,要比写代码来的直观,不足之处就是调试困难,但是昨天我的同事发现了一个调试的好办法,很不错,下一篇我会写出来. 需求是开发一个公司动态发布系统,我将未发布动态,

Django学习系列17:在模板中渲染待办事项

前面提到的问题中在表格中显示多个待办事项 是最后一个容易解决的问题.要编写一个新单元测试,检查模板是否也能显示多个待办事项: lists/tests.py def test_displays_all_list_items(self): Item.objects.create(text='itemey 1') Item.objects.create(text='itemey 2') response = self.client.get('/') self.assertIn('itemey 1',

使用resultMap实现ibatis复合数据结构查询(1.多重属性查询;2.属性中含有列表查询)

以订单为例(订单详情包括了订单的基本信息,配送物流信息,商品信息),直接上代码: 1.多重属性查询 java实体 public class OrderDetail { @XmlElement(required = true) protected String orderSn; @XmlElement(required = true) protected String orderAmount; @XmlElement(required = true) protected String orderS

sql语句中使用in、not in 查询时,注意条件范围中的null值处理事项

emp表中的数据 1. 使用in的时候,忽略为null的,不会查询出comm为null的数据 select * from emp e where e.comm in (300, 500, null); 2. 使用not in的时候,如果 not in后面的选项中没有null,只会查询从comm列不为空的列中过滤,会过滤掉comm为null的数据 select * from emp e where e.comm not in (300, 500); 3. 使用not in 的时候,如果not in

Activiti中当候选组中只有一个受理人时进行自动签收的方法

实际工作中,待办事项一般是通过用户ID进行查询的,这样比较简单.方便.在Activiti中,当绘制流程的人工任务节点时,为了便于日后维护,也为了更符合实际的场景,通常不会直接指定受理人,而是指定候选组,也就是通常说的角色.而很多时候,这个角色只有一个用户,但是在Activiti的实现中,这里面需要一个中间环节,就是签收,这个签收的过程,显得不够智能,用户会很自然的觉得多此一举,多了一步没必要的操作,那么能不能把这个环节省掉呢?本文将提供解决这个问题的方法. 这个问题,只能研究下Activiti的

Nodejs完成一个待办事项的实例教程

这是一个用Node完成的待办事项的Demo,支持手机端和PC浏览器端同时查看.下载地址:https://github.com/yangfanacc/Todo 在线查看效果可以访问这个网址:http://123.56.44.245:3460 效果图如下:首先介绍一个这个待办事项示例项目的搭建环境: 1.Nodejs版本:v0.10.35 2.Mongodb(使用Mongoose连接Mongodb数据库) 3.前台使用了国内比较好用的开源框架[Amaze](http://amazeui.org/)

待办事项不靠谱

除了看这篇文章,今天你还打算做些什么呢? 你注意到了吗?在众多类似LifeHacker.com这样的效率工具网站上,你可以发现大量压得人喘不过气的有关"又有一个新的 To-Do(待办事项)软件了"的消息.你可以在各个平台上找到大量的类似软件.现在你大概开始觉得这件事情有点可笑了,按照LifeHacker的规律(每24小时就会有一个新的To-Do软件发布),你大概需要一个To-Do软件来跟踪所有的这些To-Do软件. Life Hacker是一个主要介绍生活窍门和软件的博客网站.它的口号