新聞中心
今天我們就來(lái)看看 HistoryService 的使用。

本文使用的流程圖依然是上篇文章中使用過(guò)的,如下:
1. 查詢(xún)歷史流程
查詢(xún)歷史流程的方式很簡(jiǎn)答,如下:
@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 項(xiàng)目,所以基本上不需要什么額外的配置,直接注入 HistoryService 實(shí)例即可。
test01 方法中的代碼就是查詢(xún)出來(lái)目前所有的流程實(shí)例,包括正在執(zhí)行的和已經(jīng)執(zhí)行完畢的都可以查詢(xún)到。查詢(xún)之后,控制臺(tái)打印結(jié)果如下:
==> 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
首先大家看到,這里查詢(xún)的 SQL,查詢(xún)的表是 ACT_HI_PROCINST,簡(jiǎn)單截個(gè)圖大家看下:
大家看到,這張表中記錄了流程實(shí)例 ID,流程定義 ID,流程開(kāi)始的時(shí)間,流程結(jié)束的時(shí)間,流程執(zhí)行耗時(shí),流程開(kāi)始的節(jié)點(diǎn),流程發(fā)起人,流程結(jié)束的節(jié)點(diǎn)等等。
同時(shí)大家也可以看到,在打印出來(lái)的查詢(xún)結(jié)果中,getEndActivityId 和 getEndTime 這兩個(gè)字段的值都為 null,這就說(shuō)明這個(gè)流程目前還在執(zhí)行中,還沒(méi)執(zhí)行完畢,當(dāng)一個(gè)流程執(zhí)行完畢的時(shí)候,這兩個(gè)字段就不會(huì)為 null 了,小伙伴們可以根據(jù)這個(gè)特點(diǎn)去判斷一個(gè)流程是否執(zhí)行完畢。
現(xiàn)在根據(jù)我們上篇文章中介紹的知識(shí)點(diǎn),我將流程這個(gè)流程中的任務(wù)都執(zhí)行完畢,執(zhí)行完畢之后,ACT_RU_EXECUTION 表中關(guān)于流程的記錄就會(huì)被刪除掉,也就是執(zhí)行如下代碼現(xiàn)在是查詢(xún)不到上面這個(gè)流程了:
@Autowired
RuntimeService runtimeService;
@Test
void test02() {
ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId("a3786614-38eb-11ed-afc8-acde48001122").singleResult();
logger.info("pi:{}",pi);
}
這個(gè)方法執(zhí)行返回的 pi 對(duì)象現(xiàn)在為 null。
現(xiàn)在我們想查詢(xún)剛剛執(zhí)行的流程,得去查詢(xún)歷史流程,也就是去 ACT_HI_PROCINST 表中去查詢(xún),執(zhí)行我們最上面那個(gè)方法:
@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());
}
}
現(xiàn)在去查詢(xún),返回的結(jié)果中就可以看到 EndActivityId 以及 EndTime 這兩個(gè)字段了,因?yàn)榱鞒桃呀?jīng)執(zhí)行結(jié)束了。
通過(guò)上面的介紹,大家應(yīng)該也發(fā)現(xiàn)了,在流程執(zhí)行的過(guò)程中,ACT_HI_PROCINST 表中的流程記錄和 ACT_RU_EXECUTION 表中的流程記錄是一一對(duì)應(yīng)的。
2. 查詢(xún)歷史活動(dòng)
一個(gè)流程中的每一個(gè)節(jié)點(diǎn)都是一個(gè)活動(dòng),當(dāng)一個(gè)流程執(zhí)行結(jié)束的時(shí)候,如果我們還想查看每一個(gè)活動(dòng)執(zhí)行的細(xì)節(jié),就得通過(guò)查詢(xún)歷史活動(dòng)來(lái)實(shí)現(xiàn)了。
在查詢(xún)之前,小伙伴們先來(lái)了解下跟歷史活動(dòng)相關(guān)的兩張表。
ACT_HI_ACTINST
這張表中保存一個(gè)流程中的所有活動(dòng)細(xì)節(jié)。包括流程的啟動(dòng)節(jié)點(diǎn)、結(jié)束節(jié)點(diǎn)、各種 Task 甚至節(jié)點(diǎn)之間的連線(xiàn),大家來(lái)看下這張表中的信息:
大家看到,這剛好是一個(gè)流程的完整記錄,從上往下,分別是:
- 啟動(dòng)流程。
- 連線(xiàn)
- 提交請(qǐng)假申請(qǐng)這個(gè) UserTask
- 連線(xiàn)
- 主管審批這個(gè) UserTask
- 連線(xiàn)
- 經(jīng)理審批這個(gè) UserTask
- 連線(xiàn)
- 結(jié)束
事無(wú)巨細(xì),全部都記錄下來(lái)了。
ACT_HI_TASKINST
這個(gè)表看名字就知道只記錄下來(lái)了 Task 的信息,我截個(gè)圖大家來(lái)看下:
小伙伴們看下,這張表記錄下來(lái)了每一個(gè) Task 的具體信息,包括這個(gè) Task 是由誰(shuí)處理的,Task 的名字,開(kāi)始時(shí)間、結(jié)束時(shí)間、耗時(shí)等信息。
那么針對(duì)這兩張表,也有不同的查詢(xún)方式。
首先來(lái)看查詢(xún)歷史活動(dòng):
@Test
void test03() {
Listlist = historyService.createHistoricActivityInstanceQuery().orderByHistoricActivityInstanceStartTime().asc().list();
for (HistoricActivityInstance hai : list) {
logger.info("流程ID:{},活動(dòng)名稱(chēng):{},活動(dòng)ID:{},活動(dòng)處理人:{}",hai.getProcessInstanceId(),hai.getActivityName(),hai.getActivityId(),hai.getAssignee());
}
}
查詢(xún)結(jié)果如下圖:
小伙伴們看查詢(xún) SQL 也印證我們說(shuō)的沒(méi)有問(wèn)題。由于我這里目前只執(zhí)行了一個(gè)流程,所以這里就只顯示了一個(gè)流程的所有活動(dòng),大家看打印出來(lái)的流程 ID 都是一樣的。
再來(lái)看查詢(xún)歷史 Task:
@Test
void test04() {
Listlist = historyService.createHistoricTaskInstanceQuery().orderByHistoricTaskInstanceStartTime().asc().list();
for (HistoricTaskInstance hti : list) {
logger.info("流程ID:{},Task 開(kāi)始時(shí)間:{},Task 結(jié)束時(shí)間:{},Task 處理人:{}",hti.getProcessInstanceId(),hti.getCreateTime(),hti.getEndTime(),hti.getAssignee());
}
}
查詢(xún)結(jié)果如下:
查詢(xún) SQL 也如我們所預(yù)料的。
網(wǎng)頁(yè)標(biāo)題:如何查詢(xún)已經(jīng)執(zhí)行過(guò)的流程信息?
文章位置:http://fisionsoft.com.cn/article/djegdio.html


咨詢(xún)
建站咨詢(xún)
