Activiti 學習筆記四:流程例項、任務的執行

衣舞晨風發表於2016-09-03

一、部署流程定義

/**部署流程定義(從zip)*/
    @Test
    public void deploymentProcessDefinition_zip(){
        InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");
        ZipInputStream zipInputStream = new ZipInputStream(in);
        Deployment deployment = processEngine.getRepositoryService()//與流程定義和部署物件相關的Service
                        .createDeployment()//建立一個部署物件
                        .name("流程定義")//新增部署的名稱
                        .addZipInputStream(zipInputStream)//指定zip格式的檔案完成部署
                        .deploy();//完成部署
        System.out.println("部署ID:"+deployment.getId());//
        System.out.println("部署名稱:"+deployment.getName());//
    }

二、啟動流程例項

/**啟動流程例項*/
    @Test
    public void startProcessInstance(){
        //流程定義的key
        String processDefinitionKey = "helloworld";
        ProcessInstance pi = processEngine.getRuntimeService()//與正在執行的流程例項和執行物件相關的Service
                        .startProcessInstanceByKey(processDefinitionKey);//使用流程定義的key啟動流程例項,key對應helloworld.bpmn檔案中id的屬性值,使用key值啟動,預設是按照最新版本的流程定義啟動
        System.out.println("流程例項ID:"+pi.getId());//流程例項ID    101
        System.out.println("流程定義ID:"+pi.getProcessDefinitionId());//流程定義ID   helloworld:1:4
    }

說明:
1) 運算元據庫的act_ru_execution表,如果是使用者任務節點,同時也會在act_ru_task新增一條記錄

三、查詢我的個人任務

/** 查詢當前人的個人任務 */
    @Test
    public void findMyPersonalTask() {
        String assignee = "王五";
        List<Task> list = processEngine.getTaskService()// 與正在執行的任務管理相關的Service
                .createTaskQuery()// 建立任務查詢物件
                /** 查詢條件(where部分) */
                .taskAssignee(assignee)// 指定個人任務查詢,指定辦理人
                // .taskCandidateUser(candidateUser)//組任務的辦理人查詢
                // .processDefinitionId(processDefinitionId)//使用流程定義ID查詢
                // .processInstanceId(processInstanceId)//使用流程例項ID查詢
                // .executionId(executionId)//使用執行物件ID查詢
                /** 排序 */
                .orderByTaskCreateTime().asc()// 使用建立時間的升序排列
                /** 返回結果集 */
                // .singleResult()//返回惟一結果集
                // .count()//返回結果集的數量
                // .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("任務的建立時間:" + task.getCreateTime());
                System.out.println("任務的辦理人:" + task.getAssignee());
                System.out.println("流程例項ID:" + task.getProcessInstanceId());
                System.out.println("執行物件ID:" + task.getExecutionId());
                System.out.println("流程定義ID:" + task.getProcessDefinitionId());
                System.out.println("########################################################");
            }
        }
    }

說明:

  1. 因為是任務查詢,所以從processEngine中應該得到TaskService
  2. 使用TaskService獲取到任務查詢物件TaskQuery
  3. 為查詢物件新增查詢過濾條件,使用taskAssignee指定任務的辦理者(即查詢指定使用者的代辦任務),同時可以新增分頁排序等過濾條件
  4. 呼叫list方法執行查詢,返回辦理者為指定使用者的任務列表
  5. 任務ID、名稱、辦理人、建立時間可以從act_ru_task表中查到。
  6. 如果assignee屬性為部門經理,結果為空。因為現在流程只到了”填寫請假申請”階段,後面的任務還沒有執行,即在資料庫中沒有部門經理可以辦理的任務,所以查詢不到。
  7. 一個Task節點和Execution節點是1對1的情況,在task物件中使用Execution_來表示他們之間的關係
  8. 任務ID在資料庫表act_ru_task中對應“ID_”列

附加:
在activiti任務中,主要分為兩大類查詢任務(個人任務和組任務):

  1. 確切指定了辦理者的任務,這個任務將成為指定者的私有任務,即個人任務。
  2. 無法指定具體的某一個人來辦理的任務,可以把任務分配給幾個人或者一到 多個小組,讓這個範圍內的使用者可以選擇性(如有空餘時間時)來辦理這類任務,即組任務。

四、辦理任務

/** 完成我的任務 */
    @Test
    public void completeMyPersonalTask() {
        // 任務ID
        String taskId = "1202";
        processEngine.getTaskService()// 與正在執行的任務管理相關的Service
                .complete(taskId);
        System.out.println("完成任務:任務ID:" + taskId);
    }

說明:

  1. 是辦理任務,所以從ProcessEngine得到的是TaskService。
  2. 當執行完這段程式碼,再以員工的身份去執行查詢的時候,會發現這個時候已經沒有資料了,因為正在執行的任務中沒有資料。
  3. 對於執行完的任務,activiti將從act_ru_task表中刪除該任務,下一個任務會被插入進來。
  4. 以”部門經理”的身份進行查詢,可以查到結果。因為流程執行到部門經理審批這個節點了。
  5. 再執行辦理任務程式碼,執行完以後以”部門經理”身份進行查詢,沒有結果。
  6. 重複第3和4步直到流程執行完。

五、查詢流程狀態

(判斷流程正在執行,還是結束)

/** 查詢流程狀態(判斷流程正在執行,還是結束) */
    @Test
    public void isProcessEnd() {
        String processInstanceId = "1001";
        ProcessInstance pi = processEngine.getRuntimeService()// 表示正在執行的流程例項和執行物件
                .createProcessInstanceQuery()// 建立流程例項查詢
                .processInstanceId(processInstanceId)// 使用流程例項ID查詢
                .singleResult();
        if (pi == null) {
            System.out.println("流程已經結束");
        } else {
            System.out.println("流程沒有結束");
        }
    }

在流程執行的過程中,建立的流程例項ID在整個過程中都不會變,當流程結束後,流程例項將會在正在執行的執行物件表中(act_ru_execution)被刪除
說明:

  1. 因為是查詢流程例項,所以先獲取runtimeService
  2. 建立流程例項查詢物件,設定例項ID過濾引數
  3. 由於一個流程例項ID只對應一個例項,使用singleResult執行查詢返回一個唯一的結果,如果結果數量大於1,則丟擲異常
  4. 判斷指定ID的例項是否存在,如果結果為空,則代表流程結束,例項在正在執行的執行物件表中已被刪除,轉換成歷史資料。

六、查詢歷史任務

/** 查詢歷史任務 */
    @Test
    public void findHistoryTask() {
        String taskAssignee = "張三";
        List<HistoricTaskInstance> list = processEngine.getHistoryService()// 與歷史資料(歷史表)相關的Service
                .createHistoricTaskInstanceQuery()// 建立歷史任務例項查詢
                .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("################################");
            }
        }
    }

七、查詢歷史流程例項

/** 查詢歷史流程例項 */
    @Test
    public void findHistoryProcessInstance() {
        String processInstanceId = "1001";
        HistoricProcessInstance hpi = processEngine.getHistoryService()// 與歷史資料(歷史表)相關的Service
                .createHistoricProcessInstanceQuery()// 建立歷史流程例項查詢
                .processInstanceId(processInstanceId)// 使用流程例項ID查詢
                .singleResult();
        System.out.println(hpi.getId() + "    " + hpi.getProcessDefinitionId() + "    " + hpi.getStartTime() + "    "
                + hpi.getEndTime() + "     " + hpi.getDurationInMillis());
    }

八、總結

Execution 執行物件
按流程定義的規則執行一次的過程.
對應的表:
act_ru_execution: 正在執行的資訊
act_hi_procinst:已經執行完的歷史流程例項資訊
act_hi_actinst:存放歷史所有完成的活動(所有活動節點的歷史表)

ProcessInstance 流程例項
特指流程從開始到結束的那個最大的執行分支,一個執行的流程中,流程例項只有1個。

注意
(1)如果是單例流程,執行物件ID就是流程例項ID
(2)如果一個流程有分支和聚合,那麼執行物件ID和流程例項ID就不相同
(3)一個流程中,流程例項只有1個,執行物件可以存在多個。
比如在一個並行閘道器中
這裡寫圖片描述
當流程啟動後,會在act_ru_execution表中生成如下3條記錄,第一條是流程例項,而第2、3條則是執行物件(執行器)
這裡寫圖片描述

Task 任務
執行到某任務環節時生成的任務資訊。
對應的表:
act_ru_task:正在執行的任務資訊(只有節點是UserTask的時候,該表中存在資料)
act_hi_taskinst:已經執行完的歷史任務資訊(只有節點是UserTask的時候,該表中存在資料)

演示demo下載:http://download.csdn.net/detail/xunzaosiyecao/9621069

本文部分內容整理自itcast講義,在此表示感謝。
作者:jiankunking 出處:http://blog.csdn.net/jiankunking

相關文章