上一篇文章中我們將Activiti流程定義管理的知識進行了介紹,這篇文章我們繼續(xù)Activiti流程實例和任務管理的學習。
流程實例(ProcessInstance)和上一篇文章中流程定義(ProcessDefinition)的關系,與類和實例對象的關系有點像,ProcessDefinition是整個流程步驟的說明而ProcessInstance就是指流程定義從開始到結束的那個最大的執(zhí)行路線。
提到ProcessInstance同時又會出現(xiàn)另一個名詞,那就是執(zhí)行對象(Execution),Execution是按照ProcessDefinition的規(guī)則執(zhí)行的當前的路線,
如果ProcessDefinition只有一個執(zhí)行路線的話,那么Execution和ProcessInstance就是完全一樣了如果ProcessDefinition中有多個執(zhí)行路線的話,Execution和ProcessInstance可能是同一個也可能不是同一個。所以得出結論:一個流程中ProcessInstance有且只能有一個,而Execution可以存在多個。
任務(Task)應該比較好理解,就是當流程執(zhí)行到某步驟或某環(huán)節(jié)時生產(chǎn)的任務信息。
在上篇文章中我們將如何畫流程圖、如何部署流程定義已經(jīng)介紹,流程定義和流程實例的關系剛才已經(jīng)介紹了,所有現(xiàn)在我們就該開始啟動流程實例了:
啟動流程實例
[java] view plain copy/** * 啟動流程實例 */ @Test public void startProcessInstance() { // 流程定義的key String processDefinitionKey = "HelloWorld"; ProcessInstance pi = processEngine.getRuntimeService()// 與正在執(zhí)行的流程實例和執(zhí)行對象相關的Service .startProcessInstanceByKey(processDefinitionKey);// 使用流程定義的key啟動流程實例,key對應HelloWorld.bpmn文件中id的屬性值,使用key值啟動,默認是按照最新版本的流程定義啟動 System.out.println("流程實例ID:" + pi.getId()); System.out.println("流程定義ID:" + pi.getProcessDefinitionId()); } 運行結果:流程實例ID:501
流程定義ID:HelloWorld:2:404
說明:
1)在數(shù)據(jù)庫的act_ru_execution正在執(zhí)行的執(zhí)行對象表中插入一條記錄
2)在數(shù)據(jù)庫的act_hi_procinst程實例的歷史表中插入一條記錄
3)在數(shù)據(jù)庫的act_hi_actinst活動節(jié)點的歷史表中插入一條記錄
4)我們圖中節(jié)點都是任務節(jié)點,所以同時也會在act_ru_task流程實例的歷史表添加一條記錄
5)在數(shù)據(jù)庫的act_hi_taskinst任務歷史表中也插入一條記錄。
查詢歷史流程實例
流程實例啟動以后,我們也可以對某個流程實例一共一共執(zhí)行了多少次流程進行查詢,因為我們本例中現(xiàn)在剛進行了一個流程,所以目前只能查出一個流程:
[java] view plain copy/** * 查詢歷史流程實例 */ @Test public void findHistoryProcessInstance(){ String processInstanceId="501"; HistoricProcessInstance hpi = processEngine.getHistoryService() .createHistoricProcessInstanceQuery() .processInstanceId(processInstanceId) .singleResult(); System.out.println(hpi.getId() +" "+hpi.getProcessDefinitionId()+" "+ hpi.getStartTime()+" "+hpi.getDurationInMillis()); } 運行結果:501 HelloWorld:2:404 Fri Jun 26 09:34:51 CST 2015 null
查詢當前的個人任務
在上面講流程啟動后,因為該節(jié)點是任務節(jié)點所以在任務表中插入了任務的記錄,現(xiàn)在我們就通過辦理人將任務進行下查詢:
[java] view plain copy/** * 查詢當前的個人任務 */ @Test public void findMyPersonTask() { String assignee = "張三"; // TODO List<Task> list = processEngine.getTaskService()// 與正在執(zhí)行的任務管理相關的service .createTaskQuery()// 創(chuàng)建任務查詢對象 // 查詢條件 .taskAssignee(assignee)// 指定個人任務查詢,指定辦理人 // .taskCandidateGroup("")//組任務的辦理人查詢 // .processDefinitionId("")//使用流程定義ID查詢 // .processInstanceId("")//使用流程實例ID查詢 // .executionId(executionId)//使用執(zhí)行對象ID查詢 /** 排序 */ .orderByTaskCreateTime().asc()// 使用創(chuàng)建時間的升序排列 // 返回結果集 // .singleResult() //返回唯一的結果集 // .count()//返回結果集的數(shù)量 // .listPage(firstResult, maxResults)//分頁查詢 .list();// 返回列表 if (list != null && list.size() > 0) { for (Task task : list) { System.out.println("任務ID:" + task.getId()); System.out.println("任務名稱:" + task.getName()); System.out.println("任務的創(chuàng)建時間:" + task.getCreateTime()); System.out.println("任務的辦理人:" + task.getAssignee()); System.out.println("流程實例ID:" + task.getProcessInstanceId()); System.out.println("執(zhí)行對象ID:" + task.getExecutionId()); System.out.println("流程定義ID:" + task.getProcessDefinitionId()); System.out .println("##################################################"); } 運行結果:任務ID:504
任務名稱:提交申請
任務的創(chuàng)建時間:Fri Jun 2609:34:51 CST 2015
任務的辦理人:張三
流程實例ID:501
執(zhí)行對象ID:501
流程定義ID:HelloWorld:2:404
##################################################
說明:
1)因為是任務查詢,所以從processEngine中應該得到TaskService
2)使用TaskService獲取到任務查詢對象TaskQuery
3)為查詢對象添加查詢過濾條件,使用taskAssignee指定任務的辦理者(即查詢指定用戶的代辦任務),同時可以添加分頁排序等過濾條件
4)調用list方法執(zhí)行查詢,返回辦理者為指定用戶的任務列表
5)任務ID、名稱、辦理人、創(chuàng)建時間可以從act_ru_task表中查到。
6)在現(xiàn)在這種情況下,ProcessInstance相當于Execution
7) 一個Task節(jié)點和Execution節(jié)點是1對1的情況,在task對象中使用Execution_來表示他們之間的關系
8)任務ID在數(shù)據(jù)庫表act_ru_task中對應“ID_”列
完成任務
查詢完任務后,我們接下來將這個任務id為504的任務進行完成:
[java] view plain copy/** * 完成我的任務 */ @Test public void compliteMyPersonTask() { // 任務ID String taskId = "504"; processEngine.getTaskService().complete(taskId); ; System.out.println("完成任務:任務ID:" + taskId); } 運行結果:完成任務:任務ID:504
說明:
1)是完成任務,所以從ProcessEngine得到的是TaskService。
2)當執(zhí)行完這段代碼,再以員工的身份去執(zhí)行查詢的時候,會發(fā)現(xiàn)這個時候已經(jīng)沒有數(shù)據(jù)了,因為正在執(zhí)行的任務中沒有數(shù)據(jù)。
3)對于執(zhí)行完的任務,activiti將從act_ru_task表中刪除該任務,下一個任務會被插入進來。
4)以”部門經(jīng)理”的身份進行查詢,可以查到結果。因為流程執(zhí)行到部門經(jīng)理審批這個節(jié)點了。
5)再執(zhí)行辦理任務代碼,執(zhí)行完以后以”部門經(jīng)理”身份進行查詢,沒有結果。
6)重復第3和4步直到流程執(zhí)行完。
查詢歷史任務
員工張三的任務已經(jīng)完成,現(xiàn)在任務到部門經(jīng)理李四了,如果我們現(xiàn)在仍然查詢張三的任務的話,自然是查詢不到了,只有查詢李四才可以查到,不過我們可以通過流程實例id查詢歷史任務,查詢歷史任務可以將已經(jīng)辦理過的任務和現(xiàn)在正在執(zhí)行的任務都查詢出來:
[java] view plain copy/** * 查詢歷史任務 */ @Test public void findHistoryTask(){ String processInstanceId="501"; List<HistoricTaskInstance> list = processEngine.getHistoryService()//與歷史數(shù)據(jù)(歷史表)相關的service .createHistoricTaskInstanceQuery()//創(chuàng)建歷史任務實例查詢 .processInstanceId(processInstanceId) // .taskAssignee(taskAssignee)//指定歷史任務的辦理人 .list(); if(list!=null && list.size()>0){ for(HistoricTaskInstance hti:list){ System.out.println(hti.getId()+" "+hti.getName()+" "+hti.getProcessInstanceId()+" "+hti.getStartTime()+" "+hti.getEndTime()+" "+hti.getDurationInMillis()); System.out.println("################################"); } } } 運行結果:504 提交申請 501 Fri Jun 26 09:34:51 CST2015 Fri Jun 26 09:50:50 CST 2015 959867
################################
602 審批【部門經(jīng)理】 501 Fri Jun 26 09:50:51 CST2015 null null
################################
查詢流程是否結束
我們還可以通過流程實例id查詢某個流程現(xiàn)在的狀態(tài),是仍然在執(zhí)行過程中呢,還是流程執(zhí)行已經(jīng)結束:
[java] view plain copy/** * 查詢流程狀態(tài)(判斷流程正在執(zhí)行,還是結束) */ @Test public void isProcessEnd(){ String processInstanceId = "501"; ProcessInstance pi = processEngine.getRuntimeService()//表示正在執(zhí)行的流程實例和執(zhí)行對象 .createProcessInstanceQuery()//創(chuàng)建流程實例查詢 .processInstanceId(processInstanceId)//使用流程實例ID查詢 .singleResult(); if(pi==null){ System.out.println("流程已經(jīng)結束"); } else{ System.out.println("流程沒有結束"); } }
運行結果:
流程沒有結束
我們這篇文章主要是流程實例、執(zhí)行對象、任務以及他們之間的關系進行了學習,同時我們還將啟動和查詢流程實例、判斷流程實例是否執(zhí)行結束、查看和辦理任務以及查詢歷史任務都進行了介紹。
http://blog.csdn.net/zwk626542417/article/details/46646565
新聞熱點
疑難解答