Activiti流程管理学习笔记(二)

本文详细介绍Activiti流程引擎的使用方法,包括流程定义的部署、流程实例的启动、任务分配与查询、流程变量的设置与获取及历史流程的查询等内容。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

首先,国际惯例Helloworld:

1.新建一个activiti的project

然后在项目中的diagrams下新建一个helloworld.bpmn文件(点击项目右键-->new-->Other-->activiti-->activiti diagrams)

画一个流程图,如下:

然后在src/main/java下新建一个包和类,名字helloworld

代码如下:

public class HelloWorld {


ProcessEngine engine = ProcessEngines.getDefaultProcessEngine();

/**
* 以zip格式的文件来部署流程实例
*/
@Test
public void deployProcess(){
InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
Deployment deployment = engine.getRepositoryService().createDeployment()
.name("流程定义")
.addZipInputStream(zipInputStream)
.deploy();
System.out.println("部署流程ID:"+deployment.getId());
System.out.println("部署流程名称:"+deployment.getName());
}

//启动流程实例
@Test
public void startProcessInstance(){
String processIntanceKey = "helloworld";
ProcessInstance instance = engine.getRuntimeService()
.startProcessInstanceByKey(processIntanceKey);

System.out.println("流程实例ID:"+instance.getId());
System.out.println("流程定义ID:"+instance.getProcessDefinitionId());
System.out.println("InstanceId:"+instance.getProcessInstanceId());
}

//查看个人任务
@Test
public void searchMyTask(){
String username = "赵六";
List<Task> list = engine.getTaskService()
.createTaskQuery()
.taskAssignee(username)
.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 completeTask(){
String taskId = "402";
engine.getTaskService()
.complete(taskId);
System.out.println("完成任务的ID为:"+taskId);
}

//查询流程状态(判断流程是否正在执行还是结束。)
@Test
public void isProcessEnd(){
String processId = "101";
ProcessInstance instance = engine.getRuntimeService()
.createProcessInstanceQuery()//创建流程实例查询
.processInstanceId(processId)
.singleResult();

if(instance == null){
System.err.println("流程结束");
}else{
System.err.println("流程正在执行");
}
}

//查询历史任务,对应activiti数据库中的act_hi_taskinst表
@Test
public void historyTask(){
String username = "张三";
List<HistoricTaskInstance> list = engine.getHistoryService()
.createHistoricTaskInstanceQuery()
.taskAssignee(username)
.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("################################");
}
}
}

/**查询历史流程实例(与activiti数据库中的act_hi_procinst表对应)*/
@Test
public void findHistoryProcessInstance(){
String processInstanceId = "101";
HistoricProcessInstance hpi = engine.getHistoryService()//与历史数据(历史表)相关的Service
.createHistoricProcessInstanceQuery()//创建历史流程实例查询
.processInstanceId(processInstanceId)//使用流程实例ID查询
.singleResult();
System.out.println(hpi.getId()+"    "+hpi.getProcessDefinitionId()+"    "+hpi.getStartTime()+"    "+hpi.getEndTime()+"     "+hpi.getDurationInMillis());
}

}

每执行一个方法可以查看一下对应数据库的几张表,观察他们的变化,就可以知道流程是否正常的执行了。


2.管理流程定义

2.1画流程图(不多说)

2.2流程部署定义

2.2.1(classPath路径加载)

/**部署流程定义*/
@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入门程序  
}

说明:

1) 先获取流程引擎对象:在创建时会自动加载classpath下的activiti.cfg.xml

2) 首先获得默认的流程引擎,通过流程引擎获取了一个RepositoryService对象(仓库对象)

3) 由仓库的服务对象产生一个部署对象配置对象,用来封装部署操作的相关配置。

4) 这是一个链式编程,在部署配置对象中设置显示名,上传流程定义规则文件

5) 向数据库表中存放流程定义的规则信息。

6) 这一步在数据库中将操作三张表:

a) act_re_deployment(部署对象表)

存放流程定义的显示名和部署时间,每部署一次增加一条记录

b) act_re_procdef(流程定义表)

存放流程定义的属性信息,部署每个新的流程定义都会在这张表中增加一条记录。

注意:当流程定义的key相同的情况下,使用的是版本升级

c) act_ge_bytearray(资源文件表)

存储流程定义相关的部署信息。即流程定义文档的存放地。每部署一次就会增加两条记录,一条是关于bpmn规则文件的,一条是图片的(如果部署时只指定了bpmn一个文件,activiti会在部署时解析bpmn文件内容自动生成流程图)。两个文件不是很大,都是以二进制形式存储在数据库中。

2.2.2部署流程定义

/**部署流程定义(从zip)*/
@Test
public void deploymentProcessDefinition_inputStream(){
InputStream in = this.getClass().getResourceAsStream("diagrams/helloworld.zip");

ZipInputStream zipInputStream = new ZipInputStream(in); 
Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
.createDeployment()//创建一个部署对象
.name("连线")//添加部署的名称
.addZipInputStream(zipInputStream)//
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//
System.out.println("部署名称:"+deployment.getName());//
}

2.2.3查询流程定义

/**查询流程定义*/
@Test
public void findProcessDefinition(){
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.2.3删除流程定义

/**删除流程定义*/
@Test
public void deleteProcessDefinition(){
//使用部署ID,完成删除
String deploymentId = "601";
/**
* 不带级联的删除
*    只能删除没有启动的流程,如果流程启动,就会抛出异常
*/
// processEngine.getRepositoryService()//
// .deleteDeployment(deploymentId);

/**
* 级联删除
*  不管流程是否启动,都能可以删除
*/
processEngine.getRepositoryService()//
.deleteDeployment(deploymentId, true);
System.out.println("删除成功!");
}

2.2.4查看流程图

/**查看流程图
* @throws IOException */
@Test
public void viewPic() throws IOException{
/**将生成图片放到文件夹下*/
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盘下
FileUtils.copyInputStreamToFile(in, file);
}

2.2.5附加功能:查询最新版本的流程定义

/***附加功能:查询最新版本的流程定义*/
@Test
public void findLastVersionProcessDefinition(){
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("#########################################################");
}
}
}

2.2.6附加功能:删除流程定义(删除key相同的所有不同版本的流程定义)

@Test
public void deleteProcessDefinitionByKey(){
//流程定义的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);
}
}
}
}

2.3总结

Deployment   部署对象

1、一次部署的多个文件的信息。对于不需要的流程可以删除和修改。

2、对应的表:

  act_re_deployment:部署对象表

  act_re_procdef:流程定义表

  act_ge_bytearray:资源文件表

  act_ge_property:主键生成策略表

 

ProcessDefinition 流程定义

1、解析.bpmn后得到的流程定义规则的信息,工作流系统就是按照流程定义的规则执行的。


3.流程实例、任务的执行(用一个类里的代码,大家就可以看明白了)

public class ProcessInstanceTest {


ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

/**部署流程定义(从zip)*/
@Test
public void deploymentProcessDefinition_zip(){
InputStream in = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloworld.zip");
ZipInputStream zipInputStream = new ZipInputStream(in);
Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
.createDeployment()//创建一个部署对象
.name("流程定义")//添加部署的名称
.addZipInputStream(zipInputStream)//指定zip格式的文件完成部署
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//
System.out.println("部署名称:"+deployment.getName());//
}

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

/**查询当前人的个人任务*/
@Test
public void findMyPersonalTask(){
String assignee = "王五";
List<Task> list = processEngine.getTaskService()//与正在执行的任务管理相关的Service
.createTaskQuery()//创建任务查询对象
/**查询条件(where部分)*/
.taskAssignee(assignee)//指定个人任务查询,指定办理人
// .taskCandidateUser(candidateUser)//组任务的办理人查询
// .processDefinitionId(processDefinitionId)//使用流程定义ID查询
// .processInstanceId(processInstanceId)//使用流程实例ID查询
// .executionId(executionId)//使用执行对象ID查询
/**排序*/
.orderByTaskCreateTime().asc()//使用创建时间的升序排列
/**返回结果集*/
// .singleResult()//返回惟一结果集
// .count()//返回结果集的数量
// .listPage(firstResult, maxResults);//分页查询
.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
String taskId = "1202";
processEngine.getTaskService()//与正在执行的任务管理相关的Service
.complete(taskId);
System.out.println("完成任务:任务ID:"+taskId);
}

/**查询流程状态(判断流程正在执行,还是结束)*/
@Test
public void isProcessEnd(){
String processInstanceId = "1001";
ProcessInstance pi = processEngine.getRuntimeService()//表示正在执行的流程实例和执行对象
.createProcessInstanceQuery()//创建流程实例查询
.processInstanceId(processInstanceId)//使用流程实例ID查询
.singleResult();
if(pi==null){
System.out.println("流程已经结束");
}
else{
System.out.println("流程没有结束");
}
}

/**查询历史任务*/
@Test
public void findHistoryTask(){
String taskAssignee = "张三";
List<HistoricTaskInstance> list = processEngine.getHistoryService()//与历史数据(历史表)相关的Service
.createHistoricTaskInstanceQuery()//创建历史任务实例查询
.taskAssignee(taskAssignee)//指定历史任务的办理人
.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("################################");
}
}
}

/**查询历史流程实例*/
@Test
public void findHistoryProcessInstance(){
String processInstanceId = "1001";
HistoricProcessInstance hpi = processEngine.getHistoryService()//与历史数据(历史表)相关的Service
.createHistoricProcessInstanceQuery()//创建历史流程实例查询
.processInstanceId(processInstanceId)//使用流程实例ID查询
.singleResult();
System.out.println(hpi.getId()+"    "+hpi.getProcessDefinitionId()+"    "+hpi.getStartTime()+"    "+hpi.getEndTime()+"     "+hpi.getDurationInMillis());
}
}


小结:

Execution   执行对象

 按流程定义的规则执行一次的过程.

 对应的表:

  act_ru_execution: 正在执行的信息

  act_hi_procinst:已经执行完的历史流程实例信息

  act_hi_actinst:存放历史所有完成的活动

ProcessInstance  流程实例

 特指流程从开始到结束的那个最大的执行分支,一个执行的流程中,流程实例只有1个。

 

注意

    (1)如果是单例流程,执行对象ID就是流程实例ID

    (2)如果一个流程有分支和聚合,那么执行对象ID和流程实例ID就不相同

    (3)一个流程中,流程实例只有1个,执行对象可以存在多个。

 

Task 任务

 执行到某任务环节时生成的任务信息。

 对应的表:

  act_ru_task:正在执行的任务信息

  act_hi_taskinst:已经执行完的历史任务信息


4.流程变量

流程变量在整个工作流中扮演很重要的作用。例如:请假流程中有请假天数、请假原因等一些参数都为流程变量的范围。流程变量的作用域范围是只对应一个流程实例。也就是说各个流程实例的流程变量是不相互影响的。流程实例结束完成以后流程变量还保存在数据库中(存放到流程变量的历史表中)。


下面用一个类的代码展现:

public class ProcessVariablesTest {


ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

/**部署流程定义(从InputStream)*/
@Test
public void deploymentProcessDefinition_inputStream(){
InputStream inputStreambpmn = this.getClass().getResourceAsStream("/diagrams/processVariables.bpmn");
InputStream inputStreampng = this.getClass().getResourceAsStream("/diagrams/processVariables.png");
Deployment deployment = processEngine.getRepositoryService()//与流程定义和部署对象相关的Service
.createDeployment()//创建一个部署对象
.name("流程定义")//添加部署的名称
.addInputStream("processVariables.bpmn", inputStreambpmn)//使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完成部署
.addInputStream("processVariables.png", inputStreampng)//使用资源文件的名称(要求:与资源文件的名称要一致),和输入流完成部署
.deploy();//完成部署
System.out.println("部署ID:"+deployment.getId());//
System.out.println("部署名称:"+deployment.getName());//
}

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


/**设置流程变量*/
@Test
public void setVariables(){
/**与任务(正在执行)*/
TaskService taskService = processEngine.getTaskService();
//任务ID
String taskId = "2104";
/**一:设置流程变量,使用基本数据类型*/
// taskService.setVariableLocal(taskId, "请假天数", 5);//与任务ID绑定
// taskService.setVariable(taskId, "请假日期", new Date());
// taskService.setVariable(taskId, "请假原因", "回家探亲,一起吃个饭");
/**二:设置流程变量,使用javabean类型*/
/**
* 当一个javabean(实现序列号)放置到流程变量中,要求javabean的属性不能再发生变化
*    * 如果发生变化,再获取的时候,抛出异常
*  
* 解决方案:在Person对象中添加:
* private static final long serialVersionUID = 6757393795687480331L;
*      同时实现Serializable 
* */
Person p = new Person();
p.setId(20);
p.setName("翠花");
taskService.setVariable(taskId, "人员信息(添加固定版本)", p);

System.out.println("设置流程变量成功!");
}

/**获取流程变量*/
@Test
public void getVariables(){
/**与任务(正在执行)*/
TaskService taskService = processEngine.getTaskService();
//任务ID
String taskId = "2104";
/**一:获取流程变量,使用基本数据类型*/
// Integer days = (Integer) taskService.getVariable(taskId, "请假天数");
// Date date = (Date) taskService.getVariable(taskId, "请假日期");
// String resean = (String) taskService.getVariable(taskId, "请假原因");
// System.out.println("请假天数:"+days);
// System.out.println("请假日期:"+date);
// System.out.println("请假原因:"+resean);
/**二:获取流程变量,使用javabean类型*/
Person p = (Person)taskService.getVariable(taskId, "人员信息(添加固定版本)");
System.out.println(p.getId()+"        "+p.getName());
}

/**模拟设置和获取流程变量的场景*/
public void setAndGetVariables(){
/**与流程实例,执行对象(正在执行)*/
RuntimeService runtimeService = processEngine.getRuntimeService();
/**与任务(正在执行)*/
TaskService taskService = processEngine.getTaskService();

/**设置流程变量*/
// runtimeService.setVariable(executionId, variableName, value)//表示使用执行对象ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)
// runtimeService.setVariables(executionId, variables)//表示使用执行对象ID,和Map集合设置流程变量,map集合的key就是流程变量的名称,map集合的value就是流程变量的值(一次设置多个值)

// taskService.setVariable(taskId, variableName, value)//表示使用任务ID,和流程变量的名称,设置流程变量的值(一次只能设置一个值)
// taskService.setVariables(taskId, variables)//表示使用任务ID,和Map集合设置流程变量,map集合的key就是流程变量的名称,map集合的value就是流程变量的值(一次设置多个值)

// runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);//启动流程实例的同时,可以设置流程变量,用Map集合
// taskService.complete(taskId, variables)//完成任务的同时,设置流程变量,用Map集合

/**获取流程变量*/
// runtimeService.getVariable(executionId, variableName);//使用执行对象ID和流程变量的名称,获取流程变量的值
// runtimeService.getVariables(executionId);//使用执行对象ID,获取所有的流程变量,将流程变量放置到Map集合中,map集合的key就是流程变量的名称,map集合的value就是流程变量的值
// runtimeService.getVariables(executionId, variableNames);//使用执行对象ID,获取流程变量的值,通过设置流程变量的名称存放到集合中,获取指定流程变量名称的流程变量的值,值存放到Map集合中

// taskService.getVariable(taskId, variableName);//使用任务ID和流程变量的名称,获取流程变量的值
// taskService.getVariables(taskId);//使用任务ID,获取所有的流程变量,将流程变量放置到Map集合中,map集合的key就是流程变量的名称,map集合的value就是流程变量的值
// taskService.getVariables(taskId, variableNames);//使用任务ID,获取流程变量的值,通过设置流程变量的名称存放到集合中,获取指定流程变量名称的流程变量的值,值存放到Map集合中

}

/**完成我的任务*/
@Test
public void completeMyPersonalTask(){
//任务ID
String taskId = "2402";
processEngine.getTaskService()//与正在执行的任务管理相关的Service
.complete(taskId);
System.out.println("完成任务:任务ID:"+taskId);
}

/**查询流程变量的历史表*/
@Test
public void findHistoryProcessVariables(){
List<HistoricVariableInstance> list = processEngine.getHistoryService()//
.createHistoricVariableInstanceQuery()//创建一个历史的流程变量查询对象
.variableName("请假天数")
.list();
if(list!=null && list.size()>0){
for(HistoricVariableInstance hvi:list){
System.out.println(hvi.getId()+"   "+hvi.getProcessInstanceId()+"   "+hvi.getVariableName()+"   "+hvi.getVariableTypeName()+"    "+hvi.getValue());
System.out.println("###############################################");
}
}
}
}


小结:

• 1:流程变量

在流程执行或者任务执行的过程中,用于设置和获取变量,使用流程变量在流程传递的过程中传递业务参数。

对应的表:

act_ru_variable:正在执行的流程变量表

act_hi_varinst:流程变量历史表

 

• 2:扩展知识:setVariable和setVariableLocal的区别

setVariable:设置流程变量的时候,流程变量名称相同的时候,后一次的值替换前一次的值,而且可以看到TASK_ID的字段不会存放任务ID的值

setVariableLocal:

1:设置流程变量的时候,针对当前活动的节点设置流程变量,如果一个流程中存在2个活动节点,对每个活动节点都设置流程变量,即使流程变量的名称相同,后一次的版本的值也不会替换前一次版本的值,它会使用不同的任务ID作为标识,存放2个流程变量值,而且可以看到TASK_ID的字段会存放任务ID的值

例如act_hi_varinst 表的数据:不同的任务节点,即使流程变量名称相同,存放的值也是不同的。

如图:


2:还有,使用setVariableLocal说明流程变量绑定了当前的任务,当流程继续执行时,下个任务获取不到这个流程变量(因为正在执行的流程变量中没有这个数据),所有查询正在执行的任务时不能查询到我们需要的数据,此时需要查询历史的流程变量。


5流程执行历史任务

public class HistoryQueryTest {


ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();

/**查询历史流程实例*/
@Test
public void findHistoryProcessInstance(){
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());
}

/**查询历史活动*/
@Test
public void findHistoryActiviti(){
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("#####################");
}
}
}

/**查询历史任务*/
@Test
public void findHistoryTask(){
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("################################");
}
}
}

/**查询历史流程变量*/
@Test
public void findHistoryProcessVariables(){
String processInstanceId = "2101";
List<HistoricVariableInstance> list = processEngine.getHistoryService()//
.createHistoricVariableInstanceQuery()//创建一个历史的流程变量查询对象
.processInstanceId(processInstanceId)//
.list();
if(list!=null && list.size()>0){
for(HistoricVariableInstance hvi:list){
System.out.println(hvi.getId()+"   "+hvi.getProcessInstanceId()+"   "+hvi.getVariableName()+"   "+hvi.getVariableTypeName()+"    "+hvi.getValue());
System.out.println("###############################################");
}
}
}

}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值