历史是记录流程执行过程中发生的事情,并将其永久存储的组件。与运行时数据不同,历史数据在流程实例完成以后仍保存在数据库中。
有6个历史实体:
* HistoricProcessInstance 保存当前及已结束流程实例的信息。
* HistoricVariableInstance 保存流程变量或任务变量的最新值。
* HistoricActivityInstance 保存活动(流程中的节点)的一次执行的信息。
* HistoricTaskInstance 保存当前与历史(完成及删除的)任务实例的信息。
* HistoricIdentityLink 保存任务及流程实例、当前及历史的身份关联的信息。
* HistoricDetail 保存与历史流程实例、活动实例或任务实例等有关的多种信息。
历史与当前进行中的流程实例都在数据库中保存历史实体,因此可以选择直接查询历史表,以减少对运行时流程实例数据的访问,并提高运行时执行的性能。
历史查询可以调用 HistoryService 接口中的API来完成。下面是几个例子。
<br/>
**1. 历史流程实例查询:HistoricProcessInstance**
```java
@Test
public void historicProcessInstancesQuery() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricProcessInstance> list = historyService.createHistoricProcessInstanceQuery()
.finished() //流程实例已完成
.processDefinitionId("evectionHistory:2:117504") //流程定义Id
.includeProcessVariables() //包含全局流程变量
.orderByProcessInstanceDuration()
.desc() //根据整个流程实例完成时间降序排序
.listPage(0, 10); //分页查询
list.forEach(h -> {
System.out.println("业务标识: " + h.getBusinessKey());
System.out.println("流程部署Id: " + h.getDeploymentId());
System.out.println("流程实例Id: " + h.getId());
System.out.println("完成整个流程实例所花的时间: " + h.getDurationInMillis() + "ms");
System.out.println("流程结束节点Id: " + h.getEndActivityId());
System.out.println("流程开始节点Id: " + h.getStartActivityId());
System.out.println("流程定义Id: " + h.getProcessDefinitionId());
System.out.println("流程key: " + h.getProcessDefinitionKey());
System.out.println("流程定义版本: " + h.getProcessDefinitionVersion());
System.out.println("流程实例变量: " + h.getProcessVariables());
System.out.println("");
});
//业务标识: null
//流程部署Id: 117501
//流程实例Id: 120001
//完成整个流程实例所花的时间: 148801ms
//流程结束节点Id: _7
//流程开始节点Id: _2
//流程定义Id: evectionHistory:2:117504
//流程key: evectionHistory
//流程定义版本: 2
//全局流程变量: {assignee4=赵六, assignee3=王五, assignee2=李四, assignee1=张三}
}
```
**2. 历史变量实例查询:HistoricVariableInstance**
```java
@Test
public void historicVariableInstanceQuery() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricVariableInstance> list = historyService.createHistoricVariableInstanceQuery()
.processInstanceId("120001") //流程实例Id
.orderByVariableName()
.desc() //根据变量名称降序排序
.list();
list.forEach(h -> {
System.out.println("流程变量Id: " + h.getId());
System.out.println("流程实例Id: " + h.getProcessInstanceId());
System.out.println("变量名: " + h.getVariableName());
System.out.println("变量类型: " + h.getVariableTypeName());
System.out.println("变量值: " + h.getValue());
System.out.println("");
});
//流程变量Id: 120002
//流程实例Id: 120001
//变量名: assignee4
//变量类型: string
//变量值: 赵六
//...
}
```
**3. 历史活动实例查询:HistoricActivityInstance**
```java
@Test
public void historicActivityInstanceQuery() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricActivityInstance> list = historyService.createHistoricActivityInstanceQuery()
.activityType("userTask") //活动节点类型
.processDefinitionId("evectionHistory:2:117504") //流程定义Id
.finished() //已经完成的节点
.orderByHistoricActivityInstanceEndTime()
.desc() //根据完成时间降序排序
.listPage(0, 10); //分页查询
list.forEach(h -> {
System.out.println("节点Id: " + h.getActivityId());
System.out.println("节点名称: " + h.getActivityName());
System.out.println("节点类型: " + h.getActivityType());
System.out.println("节点负责人: " + h.getAssignee());
System.out.println("流程定义Id: " + h.getProcessDefinitionId());
System.out.println("流程实例Id: " + h.getProcessInstanceId());
System.out.println("任务Id: " + h.getTaskId());
System.out.println("该节点任务完成时间: " + h.getDurationInMillis() + "ms");
System.out.println("");
});
//节点Id: _6
//节点名称: 财务审批
//节点类型: userTask
//节点负责人: 赵六
//流程定义Id: evectionHistory:2:117504
//流程实例Id: 120001
//任务Id: 127502
//该节点任务完成时间: 13696ms
//...
}
```
**4. 历史详情查询:HistoricDetail**
```java
/**
* 历史详情查询:HistoricVariableUpdate(历史变量更新记录)
*/
@Test
public void historicVariableUpdateQuery() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricVariableUpdate> list = (List) historyService.createHistoricDetailQuery()
.variableUpdates()
.processInstanceId("120001")
.orderByTime()
.asc()
.list();
}
/**
* 历史详情查询:HistoricFormProperties(历史表单参数记录)
*/
@Test
public void historicFormPropertiesQuery() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricFormProperty> list = (List) historyService.createHistoricDetailQuery()
.formProperties()
.processInstanceId("120001")
.orderByVariableName().asc()
.list();
}
```
**5. 历史任务实例查询:HistoricTaskInstance**
```java
@Test
public void historicTaskInstanceQuery() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
List<HistoricTaskInstance> list = historyService.createHistoricTaskInstanceQuery()
.finished() //已完成的任务
.processInstanceId("120001") //流程实例Id
.includeProcessVariables() //包含全局流程变量
.includeTaskLocalVariables() //包含局部流程变量
.orderByHistoricTaskInstanceDuration()
.desc() //根据任务完成时间降序排序
.listPage(0, 10); //分页查询
list.forEach(h -> {
System.out.println("任务开始时间: " + h.getStartTime());
System.out.println("任务完成时间: " + h.getEndTime());
System.out.println("任务负责人: " + h.getAssignee());
System.out.println("流程定义Id: " + h.getProcessDefinitionId());
System.out.println("流程实例Id: " + h.getProcessInstanceId());
System.out.println("任务所在节点Id: " + h.getTaskDefinitionKey());
System.out.println("任务名称: " + h.getName());
System.out.println("任务Id: " + h.getId());
System.out.println("全局变量: " + h.getProcessVariables());
System.out.println("局部变量: " + h.getTaskLocalVariables());
System.out.println("");
});
//任务开始时间: Tue Mar 01 21:08:25 CST 2022
//任务完成时间: Tue Mar 01 21:09:36 CST 2022
//任务负责人: 张三
//流程定义Id: evectionHistory:2:117504
//流程实例Id: 120001
//任务所在节点Id: _3
//任务名称: 创建出差申请
//任务Id: 120009
//全局变量: {assignee4=赵六, assignee3=王五, assignee2=李四, assignee1=张三}
//局部变量: {}
//...
}
```
**6. 身份关联信息查询:HistoricIdentityLink**
```java
@Test
public void historicIdentityLinkQuery() {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
HistoryService historyService = processEngine.getHistoryService();
//根据流程实例Id查询
List<HistoricIdentityLink> list = historyService.getHistoricIdentityLinksForProcessInstance("120001");
list.forEach(h -> {
System.out.println("流程实例Id: " + h.getProcessInstanceId());
System.out.println("任务Id: " + h.getTaskId());
System.out.println("用户: " + h.getUserId());
System.out.println("身份关联类型: " + h.getType());
System.out.println("");
});
//流程实例Id: 120001
//任务Id: null
//用户: 赵六
//身份关联类型: participant
//...
}
```
****
参考文档:https://tkjohn.github.io/flowable-userguide/#history
- Activiti流程引擎
- 工作流介绍
- Activiti是什么
- Activiti流程处理步骤
- Activiti环境搭建
- 搭建步骤
- 表结构介绍
- ActivitiAPI结构
- 认识流程符号
- 流程设计器的使用
- 流程处理步骤
- 乱码问题
- 流程实例
- 流程实例是什么
- 业务标识
- 查询流程实例
- 挂起/激活流程实例
- 个人任务
- 分配任务负责人
- 查询待办任务
- 办理权限
- 流程变量
- 流程变量类型
- 流程变量作用域
- 使用流程变量控制流程
- 组任务
- 设置任务候选人
- 组任务办理流程
- 网关
- 4种网关类型
- 排他网关
- 并行网关
- 包含网关
- 事件网关
- Spring整合Activiti
- SpringBoot整合Activiti
- Flowable流程引擎
- Flowable是什么
- Flowable与Activiti
- Flowable环境搭建
- FlowableAPI
- 流程引擎API与服务
- 流程处理步骤
- 流程部署
- 流程部署方式
- 流程定义版本
- 删除已部署的流程
- 下载资源
- 流程实例
- 什么是流程实例
- 业务标识
- 查询流程实例
- 挂起/激活流程实例
- 分配任务负责人
- 固定分配
- UEL表达式分配
- 监听器分配
- 办理权限
- 流程变量
- 流程变量类型
- 流程变量作用域
- 流程变量控制流程
- 组任务
- 设置任务候选人
- 组任务办理流程
- 网关
- 排他网关
- 并行网关
- 包含网关
- 事件网关
- 历史查询
- 查询历史
- Spring整合Flowable
- 配置文件整合
- 配置类整合
- SpringBoot整合Flowable