1. 工作流表
由圖中可以看到,依賴中已經內建了mybatis架構,在第一次初始化流程引擎(ProcessEngine)時,會自動建立24張表(圖示版本)。
act_evt_log,
act_ge_bytearray,
act_ge_property,
act_hi_actinst,
act_hi_attachment,
act_hi_comment,
act_hi_detail,
act_hi_identitylink,
act_hi_procinst,
act_hi_taskinst,
act_hi_varinst,
act_id_group,
act_id_info,
act_id_membership,
act_id_user,
act_re_deployment,
act_re_model,
act_re_procdef,
act_ru_event_subscr,
act_ru_execution,
act_ru_identitylink,
act_ru_job,
act_ru_task,
act_ru_variable
: 're’表示repository。 這個字首的表包含了流程定義和流程靜态資源 (圖檔,規則,等等)。
act_re_*
: 'ru’表示runtime。 這些運作時的表,包含流程執行個體,任務,變量,異步任務,等運作中的資料。 activiti隻在流程執行個體執行過程中儲存這些資料, 在流程結束時就會删除這些記錄。 這樣運作時表可以一直很小速度很快。
act_ru_*
: 'id’表示identity。 這些表包含身份資訊,比如使用者,組等等。
act_id_*
: 'hi’表示history。 這些表包含曆史資料,比如曆史流程執行個體, 變量,任務等等。
act_hi_*
act_ge_*
: 通用資料, 用于不同場景下。
參考:Activity工作流入門
重點介紹下一下幾張表
-
:儲存的工作流act_ge_bytearray
以及對應的圖檔.bpmn
二進制檔案.png
-
:儲存部署act_re_deployment
-
:儲存部署的流程act_re_procdef
-
:儲存等待執行的操作,包含啟動、結束事件、任務、gateway流動等act_ru_execution
-
:儲存等待執行的任務act_ru_task
-
:儲存任務執行時定義的量act_ru_variable
-
:儲存所有執行(已執行和未執行)的操作,包含啟動、結束事件、任務、gateway流動等act_hi_actinst
-
:儲存部署的流程的曆史act_hi_procinst
-
:儲存已經執行的任務act_hi_taskinst
2. 實戰
2.1 流程定義
定義一個網站開發的工作模式,開發工作準備好之後就同時讓web端、server端、mobile端同時開發,所有的都完成後才算結束。(使用eclipse或者idea插件完成制圖工作)
流程如圖:
流程代碼:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:activiti="http://activiti.org/bpmn" xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI" xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI" xmlns:tns="http://www.activiti.org/test" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" expressionLanguage="http://www.w3.org/1999/XPath" id="m1600330675002" name="" targetNamespace="http://www.activiti.org/test" typeLanguage="http://www.w3.org/2001/XMLSchema">
<process id="devWebsite" isClosed="false" isExecutable="true" name="開發網站" processType="None">
<startEvent id="startevent1" name="start"/>
<userTask activiti:exclusive="true" id="startDev" name="開發"/>
<parallelGateway gatewayDirection="Unspecified" id="mutipathDevParallelGateway" name="多線路共同開發"/>
<userTask activiti:exclusive="true" id="webDev" name="web端"/>
<userTask activiti:exclusive="true" id="serverDev" name="server端"/>
<userTask activiti:exclusive="true" id="mobileDev" name="mobile端"/>
<endEvent id="endevent1" name="end"/>
<sequenceFlow id="_8" sourceRef="startevent1" targetRef="startDev"/>
<sequenceFlow id="_9" sourceRef="startDev" targetRef="mutipathDevParallelGateway"/>
<sequenceFlow id="_10" sourceRef="mutipathDevParallelGateway" targetRef="webDev"/>
<sequenceFlow id="_11" sourceRef="mutipathDevParallelGateway" targetRef="serverDev"/>
<sequenceFlow id="_2" sourceRef="mutipathDevParallelGateway" targetRef="mobileDev"/>
<sequenceFlow id="_3" sourceRef="webDev" targetRef="endevent1"/>
<sequenceFlow id="_4" sourceRef="serverDev" targetRef="endevent1"/>
<sequenceFlow id="_5" sourceRef="mobileDev" targetRef="endevent1"/>
</process>
<bpmndi:BPMNDiagram documentation="background=#FFFFFF;count=1;horizontalcount=1;orientation=0;width=842.4;height=1195.2;imageableWidth=832.4;imageableHeight=1185.2;imageableX=5.0;imageableY=5.0" id="Diagram-_1" name="New Diagram">
<bpmndi:BPMNPlane bpmnElement="devWebsite">
<bpmndi:BPMNShape bpmnElement="startevent1" id="Shape-startevent1">
<omgdc:Bounds height="32.0" width="32.0" x="325.0" y="30.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="startDev" id="Shape-startDev">
<omgdc:Bounds height="55.0" width="85.0" x="305.0" y="135.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="mutipathDevParallelGateway" id="Shape-mutipathDevParallelGateway">
<omgdc:Bounds height="32.0" width="32.0" x="330.0" y="225.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="webDev" id="Shape-webDev">
<omgdc:Bounds height="55.0" width="85.0" x="190.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="serverDev" id="Shape-serverDev">
<omgdc:Bounds height="55.0" width="85.0" x="315.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="mobileDev" id="Shape-mobileDev">
<omgdc:Bounds height="55.0" width="85.0" x="430.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="55.0" width="85.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNShape bpmnElement="endevent1" id="Shape-endevent1">
<omgdc:Bounds height="32.0" width="32.0" x="340.0" y="465.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="32.0" width="32.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNShape>
<bpmndi:BPMNEdge bpmnElement="_2" id="BPMNEdge__2" sourceElement="mutipathDevParallelGateway" targetElement="mobileDev">
<omgdi:waypoint x="362.0" y="241.0"/>
<omgdi:waypoint x="470.0" y="315.0"/>
<omgdi:waypoint x="470.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_3" id="BPMNEdge__3" sourceElement="webDev" targetElement="endevent1">
<omgdi:waypoint x="230.0" y="400.0"/>
<omgdi:waypoint x="230.0" y="440.0"/>
<omgdi:waypoint x="340.0" y="481.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_4" id="BPMNEdge__4" sourceElement="serverDev" targetElement="endevent1">
<omgdi:waypoint x="356.0" y="400.0"/>
<omgdi:waypoint x="356.0" y="465.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_5" id="BPMNEdge__5" sourceElement="mobileDev" targetElement="endevent1">
<omgdi:waypoint x="475.0" y="400.0"/>
<omgdi:waypoint x="475.0" y="425.0"/>
<omgdi:waypoint x="372.0" y="481.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_8" id="BPMNEdge__8" sourceElement="startevent1" targetElement="startDev">
<omgdi:waypoint x="341.0" y="62.0"/>
<omgdi:waypoint x="341.0" y="135.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_9" id="BPMNEdge__9" sourceElement="startDev" targetElement="mutipathDevParallelGateway">
<omgdi:waypoint x="346.0" y="190.0"/>
<omgdi:waypoint x="346.0" y="225.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_11" id="BPMNEdge__11" sourceElement="mutipathDevParallelGateway" targetElement="serverDev">
<omgdi:waypoint x="346.0" y="257.0"/>
<omgdi:waypoint x="346.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
<bpmndi:BPMNEdge bpmnElement="_10" id="BPMNEdge__10" sourceElement="mutipathDevParallelGateway" targetElement="webDev">
<omgdi:waypoint x="330.0" y="241.0"/>
<omgdi:waypoint x="230.0" y="310.0"/>
<omgdi:waypoint x="230.0" y="345.0"/>
<bpmndi:BPMNLabel>
<omgdc:Bounds height="0.0" width="0.0" x="0.0" y="0.0"/>
</bpmndi:BPMNLabel>
</bpmndi:BPMNEdge>
</bpmndi:BPMNPlane>
</bpmndi:BPMNDiagram>
</definitions>
2.2 代碼示範
1. 建立流程引擎
private ProcessEngine getProcessEngine() {
ProcessEngineConfiguration configuration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
Properties properties = new Properties();
try {
properties = Resource.getClasspathProperties("activity.properties");
log.info("====================開始列印工作流配置=====================");
properties.forEach((key, value) -> System.out.println(key + "=" + value));
} catch (IOException e) {
e.printStackTrace();
}
configuration.setJdbcDriver(Resource.getProperty(properties, "activity.datasource.driver"));
configuration.setJdbcUrl(Resource.getProperty(properties, "activity.datasource.url"));
configuration.setJdbcUsername(Resource.getProperty(properties, "activity.datasource.username"));
configuration.setJdbcPassword(Resource.getProperty(properties, "activity.datasource.password"));
configuration.setDatabaseSchemaUpdate(Resource.getProperty(properties, "activity.databaseSchemaUpdate"));
return configuration.buildProcessEngine();
}
2. 部署流程
@Test
public void deployProcess() {
DeploymentBuilder deploymentBuilder = getProcessEngine().getRepositoryService().createDeployment();
deploymentBuilder.addClasspathResource("DevelopWebsite.bpmn");
Deployment deploy = deploymentBuilder.deploy();
System.out.println(StringUtil.format("============= 部署的流程ID為:{}=============", deploy.getId()));
}
3. 根據流程部署ID查詢流程定義ID
@Test
public void queryProcessDefinition() {
String deployId = "1";
ProcessDefinitionQuery query = getProcessEngine().getRepositoryService().createProcessDefinitionQuery();
query.deploymentId(deployId);
query.list().forEach(item -> System.out.println(StringUtil.format("============ 流程定義ID為:{} ============", item.getId())));
}
4. 根據流程定義ID啟動流程
/**
* @description: 根據流程定義ID啟動流程,涉及到兩張表:
* 1. act_ru_execution-記錄未執行的程序記錄,包含任務、gateway的執行,就像是指令。
* 2. act_ru_task:記錄未執行的任務
* @author: yulin.chen
* @date: 2020/9/17 17:19
*/
@Test
public void startProcessByProcessDefinitionId() {
String processDefinitionId = "devWebsite:1:4";
ProcessInstance instance = getProcessEngine().getRuntimeService().startProcessInstanceById(processDefinitionId);
System.out.println(StringUtil.format("============ 啟動的執行個體ID為:{} ============", instance.getId()));
}
5. 根據流程執行個體ID查詢目前執行中的任務
@Test
public void queryRuntimeTasksByProcessInstanceId() {
String processInstanceId = "2501";
TaskQuery query = getProcessEngine().getTaskService().createTaskQuery();
//根據流程執行個體id查詢
query.processInstanceId(processInstanceId);
//任務執行時間排序
query.orderByTaskCreateTime().desc();
query.list().forEach(item -> System.out.println(StringUtil.format("============ 正在執行的任務ID為:{},任務名:{} ============",
item.getId(), item.getName())));
}
6. 根據任務ID完成任務
@Test
public void execuTask() {
String taskId = "2504";
getProcessEngine().getTaskService().complete(taskId);
}