如何查詢已經執行過的流程資訊?
上篇文章和小夥伴們分享的流程操作主要是正在執行的流程,我們有一個非常常見的場景是查詢執行過的流程資訊,在上篇文章中,小夥伴們已經知道,對於正在執行的流程,會在 ACT_RU_EXECUTION 表中儲存一條對應的記錄,不過流程執行結束之後,ACT_RU_EXECUTION 表中的記錄會被刪除掉,此時要是想查詢已經執行過的流程資訊,去哪裡查詢呢?今天我們就來看看 HistoryService 的使用。
本文使用的流程圖依然是上篇文章中使用過的,如下:
1. 查詢歷史流程
查詢歷史流程的方式很簡答,如下:
@SpringBootTest public class HiTest { @Autowired HistoryService historyService; private static final Logger logger = LoggerFactory.getLogger(HiTest.class); @Test void test01() { Listlist = historyService.createHistoricProcessInstanceQuery().list(); for (HistoricProcessInstance hi : list) { logger.info("==={},{},{},{},{},{}",hi.getId(),hi.getName(),hi.getStartActivityId(),hi.getStartTime(),hi.getEndActivityId(),hi.getEndTime()); } } }
由於我們這是 Spring Boot 專案,所以基本上不需要什麼額外的配置,直接注入 HistoryService 例項即可。
test01 方法中的程式碼就是查詢出來目前所有的流程例項,包括正在執行的和已經執行完畢的都可以查詢到。查詢之後,控制檯列印結果如下:
==> Preparing: SELECT RES.* , DEF.KEY_ as PROC_DEF_KEY_, DEF.NAME_ as PROC_DEF_NAME_, DEF.VERSION_ as PROC_DEF_VERSION_, DEF.DEPLOYMENT_ID_ as DEPLOYMENT_ID_ from ACT_HI_PROCINST RES left outer join ACT_RE_PROCDEF DEF on RES.PROC_DEF_ID_ = DEF.ID_ order by RES.ID_ asc ==> Parameters: <== Total: 1 Flushing dbSqlSession flush summary: 0 insert, 0 update, 0 delete. now executing flush... --- HistoricProcessInstanceQueryImpl finished -------------------------------------------------------- ===a3786614-38eb-11ed-afc8-acde48001122,null,startEvent1,Tue Sep 20 21:53:42 CST 2022,null,null
首先大家看到,這裡查詢的 SQL,查詢的表是 ACT_HI_PROCINST,簡單截個圖大家看下:
大家看到,這張表中記錄了流程例項 ID,流程定義 ID,流程開始的時間,流程結束的時間,流程執行耗時,流程開始的節點,流程發起人,流程結束的節點等等。
同時大家也可以看到,在列印出來的查詢結果中,getEndActivityId 和 getEndTime 這兩個欄位的值都為 null,這就說明這個流程目前還在執行中,還沒執行完畢,當一個流程執行完畢的時候,這兩個欄位就不會為 null 了,小夥伴們可以根據這個特點去判斷一個流程是否執行完畢。
現在根據我們上篇文章中介紹的知識點,我將流程這個流程中的任務都執行完畢,執行完畢之後,ACT_RU_EXECUTION 表中關於流程的記錄就會被刪除掉,也就是執行如下程式碼現在是查詢不到上面這個流程了:
@Autowired RuntimeService runtimeService; @Test void test02() { ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId("a3786614-38eb-11ed-afc8-acde48001122").singleResult(); logger.info("pi:{}",pi); }
這個方法執行返回的 pi 物件現在為 null。
現在我們想查詢剛剛執行的流程,得去查詢歷史流程,也就是去 ACT_HI_PROCINST 表中去查詢,執行我們最上面那個方法:
@Test void test01() { Listlist = historyService.createHistoricProcessInstanceQuery().list(); for (HistoricProcessInstance hi : list) { logger.info("==={},{},{},{},{},{}",hi.getId(),hi.getName(),hi.getStartActivityId(),hi.getStartTime(),hi.getEndActivityId(),hi.getEndTime()); } }
現在去查詢,返回的結果中就可以看到 EndActivityId 以及 EndTime 這兩個欄位了,因為流程已經執行結束了。
通過上面的介紹,大家應該也發現了,在流程執行的過程中,ACT_HI_PROCINST 表中的流程記錄和 ACT_RU_EXECUTION 表中的流程記錄是一一對應的。
2. 查詢歷史活動
一個流程中的每一個節點都是一個活動,當一個流程執行結束的時候,如果我們還想檢視每一個活動執行的細節,就得通過查詢歷史活動來實現了。
在查詢之前,小夥伴們先來了解下跟歷史活動相關的兩張表。
ACT_HI_ACTINST
這張表中儲存一個流程中的所有活動細節。包括流程的啟動節點、結束節點、各種 Task 甚至節點之間的連線,大家來看下這張表中的資訊:
大家看到,這剛好是一個流程的完整記錄,從上往下,分別是:
- 啟動流程。
- 連線
- 提交請假申請這個 UserTask
- 連線
- 主管審批這個 UserTask
- 連線
- 經理審批這個 UserTask
- 連線
- 結束
事無鉅細,全部都記錄下來了。
ACT_HI_TASKINST
這個表看名字就知道只記錄下來了 Task 的資訊,我截個圖大家來看下:
小夥伴們看下,這張表記錄下來了每一個 Task 的具體資訊,包括這個 Task 是由誰處理的,Task 的名字,開始時間、結束時間、耗時等資訊。
那麼針對這兩張表,也有不同的查詢方式。
首先來看查詢歷史活動:
@Test void test03() { Listlist = historyService.createHistoricActivityInstanceQuery().orderByHistoricActivityInstanceStartTime().asc().list(); for (HistoricActivityInstance hai : list) { logger.info("流程ID:{},活動名稱:{},活動ID:{},活動處理人:{}",hai.getProcessInstanceId(),hai.getActivityName(),hai.getActivityId(),hai.getAssignee()); } }
查詢結果如下圖:
小夥伴們看查詢 SQL 也印證我們說的沒有問題。由於我這裡目前只執行了一個流程,所以這裡就只顯示了一個流程的所有活動,大家看列印出來的流程 ID 都是一樣的。
再來看查詢歷史 Task:
@Test void test04() { Listlist = historyService.createHistoricTaskInstanceQuery().orderByHistoricTaskInstanceStartTime().asc().list(); for (HistoricTaskInstance hti : list) { logger.info("流程ID:{},Task 開始時間:{},Task 結束時間:{},Task 處理人:{}",hti.getProcessInstanceId(),hti.getCreateTime(),hti.getEndTime(),hti.getAssignee()); } }
查詢結果如下:
查詢 SQL 也如我們所預料的。