上一篇我們看了流程定義,我們接下來看一下流程實例,任務,和執行對象。
流程實例 任務的執行
1.流程圖
2.部署流程定義
private final ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/**
* 功能: 部署流程定義zip.<br/>
* date: 2014年12月16日 下午2:09:03 <br/>
*
* @author [email protected]
*/
@Test
public void deploymentProcessDefinitionByZip() {
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());
}
3.啓動流程實例
/**
* 功能: 啓動流程實例.<br/>
* date: 2014年12月15日 下午5:25:37 <br/>
*
* @author [email protected]
*/
@Test
public void startProcessInstance() {
// 流程定義的key
String processDefinitionKey = "helloworld";
ProcessInstance pi = processEngine.getRuntimeService()// 獲取正在執行的流程實例和執行對象相關的Service
.startProcessInstanceByKey(processDefinitionKey); // 使用流程定義的key啓動流程實例
// key
// 對應helloworld.bpmn中的Id屬性
System.out.println(pi.getId()); // 流程實例Id 601
System.out.println(pi.getProcessDefinitionId()); // 流程定義Id
// helloworld:1:504
}
操作數據庫的act_ru_execution表,如果是用戶任務節點,同時也會在act_ru_task添加一條記錄
act_ru_execution #正在執行的執行對象表
執行對象ID 流程實例ID
執行對象ID 流程實例ID
4.查詢個人任務
/**
* 功能: 查詢當前人的個人任務.<br/>
* date: 2014年12月16日 上午11:00:46 <br/>
*
* @author [email protected]
*/
@Test
public void queryMyTask() {
String assignee = "李四";
List<Task> list = processEngine.getTaskService()// 獲取正在執行的任務相關的Service
.createTaskQuery()// 創建任務查詢對象
.taskAssignee(assignee)// 指定任務辦理人
// .taskCandidateUser(candidateUser) //組任務的辦理人查詢
// .processDefinitionId(processDefinitionId)//使用流程定義Id查詢
// .processInstanceId(processInstanceId) //使用流程實例Id查詢
// .executionId(executionId) //使用執行對象Id查詢
/** 排序 */
.orderByTaskCreateTime().asc() // 使用創建時間的升序
/** 返回結果集 */
// .singleResult()// 返回唯一結果集
// .count() // 返回結果集的數量
// .listPage(firstResult, maxResults)//分頁查詢
.list();
if (null != list && 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)單例流程中ProcessInstance相當於Execution
7)如果assignee屬性爲部門經理,結果爲空。因爲現在流程只到了”填寫請假申請”階段,後面的任務還沒有執行,即在數據庫中沒有部門經理可以辦理的任務,所以查詢不到
8)一個Task節點和Execution節點是1對1的情況,在task對象中使用Execution_來表示他們之間的關係
9)任務ID在數據庫表act_ru_task中對應“ID_”列
附加:
在activiti任務中,主要分爲兩大類查詢任務(個人任務和組任務):
1.確切指定了辦理者的任務,這個任務將成爲指定者的私有任務,即個人任務。
2.無法指定具體的某一個人來辦理的任務,可以把任務分配給幾個人或者一到多個小組,讓這個範圍內的用戶可以選擇性(如有空餘時間時)來辦理這類任務,即組任務。
act_ru_task #正在執行的任務表
任務ID 執行對象ID 流程實例ID
act_hi_taskinst #任務歷史表
辦理人 開始時間 結束時間
act_hi_actinst #所有活動節點的歷史表
5.辦理任務
/**
* 功能: 完成任務.<br/>
* date: 2014年12月17日 下午5:24:44 <br/>
*
* @author [email protected]
*/
@Test
public void completeMyTask() {
String taskId = "1402";
processEngine.getTaskService()// 獲取任務相關Service
.complete(taskId);
System.out.println("完成任務:任務ID:" + taskId);
}
說明:
1)是辦理任務,所以從ProcessEngine得到的是TaskService
2)當執行完這段代碼,再以員工的身份去執行查詢的時候,會發現這個時候已經沒有數據了,因爲正在執行的任務中沒有數據
3)對於執行完的任務,activiti將從act_ru_task表中刪除該任務,下一個任務會被插入進來
4)以”部門經理”的身份進行查詢,可以查到結果。因爲流程執行到部門經理審批這個節點了
5)再執行辦理任務代碼,執行完以後以”部門經理”身份進行查詢,沒有結果、
6)重複第3和4步直到流程執行完
6.查詢流程狀態
/**
* 功能: 查詢流程狀態(判斷流程正在執行,還是結束).<br/>
* date: 2014年12月22日 下午3:52:22 <br/>
*
* @author [email protected]
*/
@Test
public void isProcessEnd() {
String processInstanceId = "1201";
ProcessInstance pi = processEngine.getRuntimeService()// 正在執行的流程實例和執行對象相關Service
.createProcessInstanceQuery() // 創建流程實例查詢
.processInstanceId(processInstanceId) // 使用流程實例ID查詢
.singleResult();
if (null == pi) {
System.out.println("流程已經結束!");
} else {
System.out.println("流程正在執行!");
}
}
在流程執行的過程中,創建的流程實例ID在整個過程中都不會變,當流程結束後,流程實例將會在正在執行的執行對象表中(act_ru_execution)被刪除
說明:
1)因爲是查詢流程實例,所以先獲取runtimeService
2)創建流程實例查詢對象,設置實例ID過濾參數
3)由於一個流程實例ID只對應一個實例,使用singleResult執行查詢返回一個唯一的結果,如果結果數量大於1,則拋出異常
4)判斷指定ID的實例是否存在,如果結果爲空,則代表流程結束,實例在正在執行的執行對象表中已被刪除,轉換成歷史數據
7.查詢歷史任務
/**
* 功能: 查詢歷史任務.<br/>
* date: 2014年12月22日 下午4:15:55 <br/>
*
* @author [email protected]
*/
@Test
public void findHistoryTask() {
String taskAssignee = "張三";
List<HistoricTaskInstance> list = processEngine.getHistoryService()// 與歷史數據相關的Service
.createHistoricTaskInstanceQuery() // 創建歷史任務實例查詢
.taskAssignee(taskAssignee) // 指定辦理人
.list();
if (null != list && list.size() > 0) {
for (HistoricTaskInstance hist : list) {
System.out.println(hist.getId() + " " + hist.getName() + " " + hist.getProcessInstanceId() + " "
+ hist.getStartTime());
System.out.println("#########################");
}
}
}
8.查詢歷史流程實例
/**
* 功能: 查詢歷史流程實例.<br/>
* date: 2014年12月22日 下午4:25:13 <br/>
*
* @author [email protected]
*/
@Test
public void findHistoryProcessInstance() {
String processInstanceId = "1201";
HistoricProcessInstance hpi = processEngine.getHistoryService()// 與歷史數據相關的Service
.createHistoricProcessInstanceQuery() // 創建歷史流程實例查詢
.processInstanceId(processInstanceId) // 使用流程實例Id查詢
.singleResult();
System.out.println(hpi.getId() + " " + hpi.getProcessDefinitionId() + " " + hpi.getStartTime() + " "
+ hpi.getEndTime());
}
總結:
Execution 執行對象
按流程定義的規則執行一次的過程.
對應的表:
act_ru_execution:正在執行的信息
act_hi_procinst:已經執行完的歷史流程實例信息
act_hi_actinst:存放歷史所有完成的活動
ProcessInstance 流程實例
特指流程從開始到結束的那個最大的執行分支,一個執行的流程中,流程實例只有1個。
注意
(1)如果是單例流程,執行對象ID就是流程實例ID
(2)如果一個流程有分支和聚合,那麼執行對象ID和流程實例ID就不相同
(3)一個流程中,流程實例只有1個,執行對象可以存在多個
Task任務
執行到某任務環節時生成的任務信息
對應的表:
act_ru_task:正在執行的任務信息
act_hi_taskinst:已經執行完的歷史任務信息