Activiti5 学习笔记(一)—— 入门

引用jar包 

<dependency>
			<groupId>org.activiti</groupId>
			<artifactId>activiti-engine</artifactId>
			<version>5.22.0</version>
		</dependency>

安装流程设计器(eclipse插件)

在线安装:
Name: Activiti BPMN 2.0 designer
Location: http://activiti.org/designer/update/

离线安装包:https://github.com/Activiti/Activiti-Designer/releases
在安装离线安装包时,需要下载4个eclipse的插件,否则activiti插件包安装时会报错
org.eclipse.emf.transaction-1.8.0.201405281451.jar
org.eclipse.emf.validation.ui-1.7.0.201405281429.jar
org.eclipse.emf.validation-1.8.0.201405281429.jar
org.eclipse.emf.workspace-1.5.1.201405281451.jar
以上四个jar可以在maven仓库https://dist.wso2.org/maven2/处下载

如果在安装离线包的时候可以互联网,建议先断开;否则会出现联网更新,导致安装一直没有进度。

生成流程图片(非必须)

打开菜单Windows->Preferences->Activiti->Save下流程流程图片的生成方式:

虽然流程引擎在单独部署bpmn文件时会自动生成图片,但在实际开发过程中,自动生成的图片会导致和BPMN中的坐标有出入,在实际项目中展示流程当前位置图会有问题。所在完成以上配置后,会由我们自己来管理流程图片。在发布流程时把流程规则文件和流程图片一起上传就行了。

初始化数据库

public static void main(String[] args) {
        ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
        //连接数据库的配置
        processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");
        processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8");
        processEngineConfiguration.setJdbcUsername("root");
        processEngineConfiguration.setJdbcPassword("root");
        
        /**
         *  数据库初始化策略
            public static final String DB_SCHEMA_UPDATE_FALSE = "false";不能自动创建表,需要表存在
            public static final String DB_SCHEMA_UPDATE_CREATE_DROP = "create-drop";先删除表再创建表
            public static final String DB_SCHEMA_UPDATE_TRUE = "true";如果表不存在,自动创建表
         */
        processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
        //工作流的核心对象,ProcessEnginee对象
        ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
        System.out.println("processEngine:"+processEngine);
    }

如果程序正常执行,mysql会自动建库,然后创建23张表 

根据xml文件初始化数据库

创建activiti.cfg.xml

<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
	http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">


    <!-- dbcp数据源-->
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
          <property name="url" value="jdbc:mysql://localhost:3306/activiti?useUnicode=true&amp;characterEncoding=utf8"></property>
          <property name="username" value="root"></property>
          <property name="password" value="root"></property>
    </bean>
	
	<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
		
            <!-- 使用默认的MyBatis连接池配置数据源,还有一些连接池参数就不展示了,实际开发中都不会使用用默认 -->
		<property name="jdbcDriver" value="com.mysql.jdbc.Driver"></property>
		<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti?useUnicode=true&amp;characterEncoding=utf8"></property>
		<property name="jdbcUsername" value="root"></property>
		<property name="jdbcPassword" value="root"></property>
		
		<!-- 使用其他数据源 -->
		<!-- <property name="dataSource" ref="dataSource"></property> -->

		<!-- 
			databaseSchemaUpdate=true   如果表不存在,自动创建表
			databaseSchemaUpdate=false  默认值,不自动创建表,需要表存在
			databaseSchemaUpdate=create-drop  如果表不存在,自动创建表
		 -->
		<property name="databaseSchemaUpdate" value="true"></property>
	</bean>

</beans>
public static void main(String[] args) {
        //指定路径加载,这里的路是指classpath下的路径
        ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("config/activiti.cfg.xml")
                .buildProcessEngine();
        //默认路径加载,默认路径为:classpath:activiti.cfg.xml
        //ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();  
        System.out.println("processEngine:" + processEngine);
    }

 创建一个流程,这里以userTask流程为例

1. 在src/main/resources/diagrams路径下创建helloworld.bpmn

2. 编写入门示例代码

第一步:获取流程引擎

ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

第二步:部署流程定义

//部署流程方式1:从classpath下加载.bpmn和.png
Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
	 .createDeployment()//创建一个部署对象
	 .name("helloworld入门程序")//添加部署的名称
	 .addClasspathResource("diagrams/helloworld.bpmn")//从classpath的资源中加载,一次只能加载一个文件
	 //.addClasspathResource("diagrams/helloworld.png")//从classpath的资源中加载,一次只能加载一个文件,非必须,如果没有创建png,默认会在数据库中自动创建
	 .deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());

//部署流程方式2:从zip包加载
//zip包只能包含.bpmn和.png文件
InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/test.zip"); //获取zip包的输入流对象
ZipInputStream zipInputStream = new ZipInputStream(in);
Deployment deployment = processEngine.getRepositoryService()
	.createDeployment()
	.name("helloworld入门程序")
	.addZipInputStream(zipInputStream) //指定zip格式的文件完成部署
	.deploy();

//部署流程方式3:从InputStream加载
InputStream inputStreambpmn = this.getClass().getResourceAsStream("/diagrams/helloworld.bpmn"); //获取.bpmn的输入流
InputStream inputStreampng = this.getClass().getResourceAsStream("/diagrams/helloworld.png"); //获取.png的输入流
Deployment deployment = processEngine.getRepositoryService()
	.createDeployment()
	.name("helloworld入门程序")
	.addInputStream("helloworld-inputStream.bpmn", inputStreambpmn)  //添加资源文件,名称可以随便取
	.addInputStream("helloworld-inputStream.png", inputStreampng)  //添加资源文件,名称可以随便取
	.deploy();//完成部署

综上所述:流程图画好之后,需要先进行部署才能使用;但是需要注意的是,如果流程图没有发生变化,最好不要每次启动程序的时候就去调用部署代码,这样会造成流程部署表和流程定义表的数据一直在发生变化,实际上流程本身并没有变化。

第三步:启动流程实例

//启动流程实例,也就是开始执行流程了,从开始节点到结束节点,依次执行;
//当一个流程启动后,流程实例会贯穿整个流程,流程实例id是不会发生变化的
String processDefinitionKey = "helloworld";  //key对应helloworld.bpmn文件中id的属性值,使用key值启动,当流程定义表中存在多个相同的key值时,默认是按照最新版本的流程定义启动
ProcessInstance pi = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的Service
	.startProcessInstanceByKey(processDefinitionKey);//使用流程定义的key启动流程实例,
System.out.println("流程实例ID:"+pi.getId());//流程实例ID    
System.out.println("流程定义ID:"+pi.getProcessDefinitionId());//流程定义ID 

 综上所述:带ID的字段基本都是主键,各表之间相互引用关联。

第四步:查询任务

//当前节点为提交申请,办理人为张三
String assignee = "张三";  //对应helloworld.bpmn-properties-mianconfig-assignee
List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
	.createTaskQuery()//创建任务查询对象
	.taskAssignee(assignee)//指定任务办理人
	.list();
if(list!=null && 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());
    }
}
任务ID:2504
任务名称:提交申请
任务的创建时间:Sun Jan 05 20:55:31 CST 2020
任务的办理人:张三
流程实例ID:2501
执行对象ID:2501
流程定义ID:helloworld:1:4

第五步:完成任务

//模拟张三完成了任务,进入下一个节点
String taskId = "2504";  //act_ru_task表的id
processEngine.getTaskService().complete(taskId); 
System.out.println("完成任务:任务ID:"+taskId);

第六步:依次查询任务和完成任务

//模拟最后一个节点王五完成任务
String taskId = "7502";  //act_ru_task表的id
processEngine.getTaskService().complete(taskId); 
System.out.println("完成任务:任务ID:"+taskId);

完整的代码如下:

package cn.fg.activiti.general;

import java.util.List;

import org.activiti.engine.ProcessEngine;
import org.activiti.engine.ProcessEngines;
import org.activiti.engine.repository.Deployment;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.Task;
import org.junit.Test;

public class Test03 {
    
    ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();  //默认加载类路径下的activiti.cfg.xml

    /**第一步:部署流程定义*/
    @Test
    public void deploymentProcessDefinition(){
        Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
                        .createDeployment()//创建一个部署对象
                        .name("helloworld入门程序")//添加部署的名称
                        .addClasspathResource("diagrams/helloworld.bpmn")//从classpath的资源中加载,一次只能加载一个文件
                        //.addClasspathResource("diagrams/helloworld.png")//从classpath的资源中加载,一次只能加载一个文件
                        .deploy();//完成部署
        System.out.println("部署ID:"+deployment.getId());//1
        System.out.println("部署名称:"+deployment.getName());//helloworld入门程序  
        
        //涉及数据表
        //act_re_deployment 部署对象表
        //act_re_procdef    流程定义表
        //act_ge_bytearray  资源文件表
        //act_ge_property   属性表,主键生成策略

    }
    
    /**第二步:启动流程实例,流程开始执行,进入提交申请节点 */
    @Test
    public void startProcessInstance(){
        //流程定义表中的key对用流程图的id
        String processDefinitionKey = "helloworld";
        ProcessInstance pi = processEngine.getRuntimeService()//与正在执行的流程实例和执行对象相关的Service
                        .startProcessInstanceByKey(processDefinitionKey);//使用流程定义的key启动流程实例,key对应helloworld.bpmn文件中id的属性值,使用key值启动,默认是按照最新版本的流程定义启动
        System.out.println("流程实例ID:"+pi.getId());//流程实例ID    101

        //流程定义ID   helloworld:1:4    helloworld表示.bpmn文件的id值(act_re_procdef表的key值),1表示当前版本,4表示随机生成的,更改流程图后版本号会变化,每次启动流程实例都是以最新版本号启动的
        System.out.println("流程定义ID:"+pi.getProcessDefinitionId());
        //启动后进入第二个节点
        
        
        //涉及数据表
        //act_ru_execution        增在执行的执行对象
        //act_hi_procinst         流程实例历史表
        //act_ru_identitylink     
        //act_ru_task             正在执行的任务表(只有流程节点是userTask时此表才会有数据)
        //act_hi_taskinst         任务历史表(只有流程节点是userTask时此表才会有数据
        //act_hi_actinst          所有活动节点的历史表
    }
    
    /**第三步:查询办理人张三的任务*/
    @Test
    public void findMyPersonalTask(){
        String assignee = "张三";  //对应helloworld.bpmn-properties-mianconfig-assignee
        List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
                        .createTaskQuery()//创建任务查询对象
                        .taskAssignee(assignee)//指定个人任务查询,指定办理人
                        .list();
        if(list!=null && 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("########################################################");
            }
        }
    }
    
    /**第四步:模拟张三完成任务,进入下一个节点*/
    @Test
    public void completeMyPersonalTask(){
        //任务ID,步骤3输出的任务id
        String taskId = "12502";  //act_ru_task表的id
        processEngine.getTaskService()//与正在执行的任务管理相关的Service
                    .complete(taskId);  //act_ru_task表id为5004的记录消失,进入下一个节点
        System.out.println("完成任务:任务ID:"+taskId);
        
        //涉及数据表
        //act_hi_taskinst        任务历史

    }

    /**第五步:查询办理人李四的任务*/
    @Test
    public void findMyPersonalTask(){
        //同步骤三
        String assignee = "李四";       
    }

    /**第六步:模拟李四完成任务,进入下一个节点*/
    @Test
    public void completeMyPersonalTask(){
        //同步骤四
        String taskId = "";     
    }
    
    .......不再写了,就是要查任务,完成任务。
  
}

数据库表说明

Activiti的数据库名称都以ACT_开头,第二部分的两个字母表示用例标识。 用例标识和服务API对应(例如ACT_RE_*表和RuntimeService的API对应,即RuntimeService类可以操作ACT_RE_*表的CRUD)

ACT_RE_ *:RE代表repository。具有此前缀的表包含静态信息,例如流程定义和流程资源(图像,规则等)。
ACT_RU_ *:RU代表runtime。这些是运行时表,其中包含流程实例,用户任务,变量,作业等的运行时数据。Activiti仅在流程实例执行期间存储运行时数据,并在流程实例结束时删除记录。这样可以使运行时表较小而又快速。
ACT_ID_ *:ID代表identity。这些表包含身份信息,例如用户,组等。
ACT_HI_ *:HI代表history。这些表包含历史数据,例如过去的流程实例,变量,任务等。
ACT_GE_ *:general通用数据,用于不同的场景中。

具体的表结构查询:https://www.devdoc.cn/activiti-table-summary.html

核心API

1. ProcessEngine

 在Activiti中最核心的类,其他的类都是由他而来,创建该类的方式

//方式一:使用编码的方式创建
ProcessEngineConfiguration processEngineConfiguration = ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
processEngineConfiguration.setJdbcDriver("com.mysql.jdbc.Driver");
processEngineConfiguration.setJdbcUrl("jdbc:mysql://localhost:3306/activiti?useUnicode=true&characterEncoding=utf8");
processEngineConfiguration.setJdbcUsername("root");
processEngineConfiguration.setJdbcPassword("root");
processEngineConfiguration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);

ProcessEngine processEngine = processEngineConfiguration.buildProcessEngine();
//方式二:指定xml文件路径创建,该路径是classpath下的路径
ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource("config/activiti.cfg.xml").buildProcessEngine();
//方式三:使用默认流程引擎,默认使用classpath下的activiti.cfg.xml文件创建
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

2. RepositoryService

是Activiti的仓库服务类。所谓的仓库指流程定义文档的两个文件:bpmn文件和流程图片。

RepositoryService repositoryService = processEngine.getRepositoryService();

3. RuntimeService

是activiti的流程执行服务类。可以从这个服务类中获取很多关于流程执行相关的信息。

RuntimeService runtimeService = processEngine.getRuntimeService();

4. TaskService

是activiti的任务服务类。可以从这个类中获取任务的信息。

TaskService taskService = processEngine.getTaskService();

5. HistoryService

是activiti的查询历史信息的类。在一个流程执行完成后,这个对象为我们提供查询历史信息。

HistoryService historyService = processEngine.getHistoryService();

6. ProcessDefinition

流程定义类。可以从这里获得资源文件等。

7. ProcessInstance

代表流程定义的执行实例。如范冰冰请了一天的假,她就必须发出一个流程实例的申请。一个流程实例包括了所有的运行节点。我们可以利用这个对象来了解当前流程实例的进度等信息。流程实例就表示一个流程从开始到结束的最大的流程分支,即一个流程中流程实例只有一个。

8. Execution

Activiti用这个对象去描述流程执行的每一个节点。一个流程中,执行对象可以存在多个,但是流程实例只能有一个。在没有并行任务的情况下,Execution就是ProcessInstance。

流程定义的CRUD

1. 查询流程定义

List<ProcessDefinition> list = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
	.createProcessDefinitionQuery()//创建一个流程定义的查询
	/**指定查询条件,where条件*/
	//.deploymentId(deploymentId)//使用部署对象ID查询
	//.processDefinitionId(processDefinitionId)//使用流程定义ID查询
	//.processDefinitionKey(processDefinitionKey)//使用流程定义的key查询
	//.processDefinitionNameLike(processDefinitionNameLike)//使用流程定义的名称模糊查询
	
	/**排序*/
	.orderByProcessDefinitionVersion().asc()//按照版本的升序排列
	//.orderByProcessDefinitionName().desc()//按照流程定义的名称降序排列
	
	/**返回的结果集*/
	.list();//返回一个集合列表,封装流程定义
	//.singleResult();//返回惟一结果集
	//.count();//返回结果集数量
	//.listPage(firstResult, maxResults);//分页查询
if(list!=null && list.size()>0){
	for(ProcessDefinition pd:list){
		System.out.println("流程定义ID:"+pd.getId());//流程定义的key+版本+随机生成数
		System.out.println("流程定义的名称:"+pd.getName());//对应helloworld.bpmn文件中的name属性值
		System.out.println("流程定义的key:"+pd.getKey());//对应helloworld.bpmn文件中的id属性值
		System.out.println("流程定义的版本:"+pd.getVersion());//当流程定义的key值相同的相同下,版本升级,默认1
		System.out.println("资源名称bpmn文件:"+pd.getResourceName());
		System.out.println("资源名称png文件:"+pd.getDiagramResourceName());
		System.out.println("部署对象ID:"+pd.getDeploymentId());
		System.out.println("#########################################################");
	}
}	

//查询其他对象也是一样的方式,这里就不再介绍了

2. 删除流程定义

//使用部署ID,完成删除
String deploymentId = "601";

//不带级联的删除,只能删除没有启动的流程,如果流程启动,就会抛出异常
processEngine.getRepositoryService().deleteDeployment(deploymentId);

processEngine.getRepositoryService().createDeploymentQuery().

//级联删除,不管流程是否启动,都能可以删除
processEngine.getRepositoryService().deleteDeployment(deploymentId, true);

System.out.println("删除成功!");

3. 查看流程图

//部署ID		
String deploymentId = "801";

//获取图片资源名称
List<String> list = processEngine.getRepositoryService().getDeploymentResourceNames(deploymentId);

//定义图片资源的名称
String resourceName = "";
if(list!=null && list.size()>0){
	for(String name:list){
		if(name.indexOf(".png")>=0){
			resourceName = name;
		}
	}
}

//获取图片的输入流
InputStream in = processEngine.getRepositoryService().getResourceAsStream(deploymentId, resourceName);

//将图片生成到D盘的目录下
File file = new File("D:/"+resourceName);

//将输入流的图片写到D盘下
org.apache.commons.io.FileUtils.copyInputStreamToFile(in, file);

4. 查询最新版本的流程定义

List<ProcessDefinition> list = processEngine.getRepositoryService()
	.createProcessDefinitionQuery()//
	.orderByProcessDefinitionVersion().asc()//使用流程定义的版本升序排列
	.list();

/**
  Map<String,ProcessDefinition>
  map集合的key:流程定义的key
  map集合的value:流程定义的对象
  map集合的特点:当map集合key值相同的情况下,后一次的值将替换前一次的值
*/
Map<String, ProcessDefinition> map = new LinkedHashMap<String, ProcessDefinition>();
if(list!=null && list.size()>0){
	for(ProcessDefinition pd:list){
		map.put(pd.getKey(), pd);
	}
}

List<ProcessDefinition> pdList = new ArrayList<ProcessDefinition>(map.values());
if(pdList!=null && pdList.size()>0){
	for(ProcessDefinition pd:pdList){
		System.out.println("流程定义ID:"+pd.getId());//流程定义的key+版本+随机生成数
		System.out.println("流程定义的名称:"+pd.getName());//对应helloworld.bpmn文件中的name属性值
		System.out.println("流程定义的key:"+pd.getKey());//对应helloworld.bpmn文件中的id属性值
		System.out.println("流程定义的版本:"+pd.getVersion());//当流程定义的key值相同的相同下,版本升级,默认1
		System.out.println("资源名称bpmn文件:"+pd.getResourceName());
		System.out.println("资源名称png文件:"+pd.getDiagramResourceName());
		System.out.println("部署对象ID:"+pd.getDeploymentId());
		System.out.println("#########################################################");
	}
}

5. 删除流程定义(删除key相同的所有不同版本的流程定义)

//流程定义的key
String processDefinitionKey = "helloworld";

//先使用流程定义的key查询流程定义,查询出所有的版本
List<ProcessDefinition> list = processEngine.getRepositoryService()//
	.createProcessDefinitionQuery()//
	.processDefinitionKey(processDefinitionKey)//使用流程定义的key查询
	.list();

//遍历,获取每个流程定义的部署ID
if(list!=null && list.size()>0){
	for(ProcessDefinition pd:list){
		//获取部署ID
		String deploymentId = pd.getDeploymentId();
		processEngine.getRepositoryService().deleteDeployment(deploymentId, true);
	}
}

6. 对于修改操作是有限制的,一般使用set方法,能set的就可以修改

processEngine.getRepositoryService().setProcessDefinitionCategory(processDefinitionId, category);

7. 判断流程是否结束 

String processInstanceId = "2504";

/**判断流程是否结束,查询正在执行的执行对象表*/
ProcessInstance rpi = processEngine.getRuntimeService()//
				.createProcessInstanceQuery()//创建流程实例查询对象
				.processInstanceId(processInstanceId)
				.singleResult();

//说明流程实例结束了
if(rpi==null){
	/**查询历史,获取流程的相关信息*/
	HistoricProcessInstance hpi = processEngine.getHistoryService()//
				.createHistoricProcessInstanceQuery()//
				.processInstanceId(processInstanceId)//使用流程实例ID查询
				.singleResult();
	System.out.println(hpi.getId()+"    "+hpi.getStartTime()+"   "+hpi.getEndTime()+"   "+hpi.getDurationInMillis());
}

查询历史

1. 查询历史流程实例

String processInstanceId = "2101";
HistoricProcessInstance hpi = processEngine.getHistoryService()//与历史数据(历史表)相关的Service
	.createHistoricProcessInstanceQuery()//创建历史流程实例查询
	.processInstanceId(processInstanceId)//使用流程实例ID查询
	.orderByProcessInstanceStartTime().asc()
	.singleResult();
System.out.println(hpi.getId()+"    "+hpi.getProcessDefinitionId()+"    "+hpi.getStartTime()+"    "+hpi.getEndTime()+"     "+hpi.getDurationInMillis());

2. 查询历史活动节点(act_hi_actinst)

String processInstanceId = "2101";
List<HistoricActivityInstance> list = processEngine.getHistoryService()//
	.createHistoricActivityInstanceQuery()//创建历史活动实例的查询
	.processInstanceId(processInstanceId)//
	.orderByHistoricActivityInstanceStartTime().asc()//
	.list();
if(list!=null && list.size()>0){
	for(HistoricActivityInstance hai:list){
		System.out.println(hai.getId()+"   "+hai.getProcessInstanceId()+"   "+hai.getActivityType()+"  "+hai.getStartTime()+"   "+hai.getEndTime()+"   "+hai.getDurationInMillis());
		System.out.println("#####################");
	}
}

3. 查询历史任务

String processInstanceId = "2101";
List<HistoricTaskInstance> list = processEngine.getHistoryService()//与历史数据(历史表)相关的Service
	.createHistoricTaskInstanceQuery()//创建历史任务实例查询
	.processInstanceId(processInstanceId)//
	.orderByHistoricTaskInstanceStartTime().asc()
	.list();
if(list!=null && list.size()>0){
	for(HistoricTaskInstance hti:list){
		System.out.println(hti.getId()+"    "+hti.getName()+"    "+hti.getProcessInstanceId()+"   "+hti.getStartTime()+"   "+hti.getEndTime()+"   "+hti.getDurationInMillis());
		System.out.println("################################");
	}
}
发布了64 篇原创文章 · 获赞 0 · 访问量 3188

猜你喜欢

转载自blog.csdn.net/q42368773/article/details/103795777
今日推荐