以请假单为例, 流程变量的意义在于将请假单跟这个流程绑定在一起, 流程走到哪里, 请假单的状态就跟到哪里, 相当于定义了一个流程变量来存储相对应的状态.
流程变量存在两个级别位置, 一是流程实例级别的的流程变量(在流程实例启动时就将流程变量放入), 二是流程任务级别的流程变量(在执行当前任务时将流程变量放入)
10张表:
SELECT * FROM act_re_deployment; -- 一 流程部署表
SELECT * FROM act_ge_bytearray; -- 二 流程二进制表
SELECT * FROM act_re_procdef; -- 三 流程定义表
SELECT * FROM act_ru_execution; -- 四 流程正在运行表
SELECT * FROM act_hi_procinst; -- 五 流程实例历史表
SELECT * FROM act_ru_task; -- 六 流程当前任务表
SELECT * FROM act_hi_taskinst; -- 七 流程历史任务表
SELECT * FROM act_hi_actinst; -- 八 流程历史活动节点表
SELECT * FROM act_ru_variable; -- 九 流程变量表
SELECT * FROM act_hi_varinst; -- 十 流程变量历史表
先决条件:
//定义一个成员变量
RepositoryService repositoryService;
RuntimeService runtimeService;
TaskService taskService;
/**
* 获取流程引擎
*/
@Before
public void setUp() throws Exception {
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
repositoryService = processEngine.getRepositoryService();
runtimeService = processEngine.getRuntimeService();
taskService = processEngine.getTaskService();
}
/**
* 添加流程实例级别的流程变量并启动流程
*/
@Test
public void startProcessInstanceWithVariables() {
Map map = new HashMap();
map.put("请假天数", 3);
map.put("请假原因", "出国留学了");
map.put("请假开始时间", new Date());
runtimeService.startProcessInstanceByKey("activiti_leave", map);
}
① 流程实例级别的流程变量(流程实例范围大, 能被范围小的流程任务获取到)
流程任务对象/流程正在执行对象查询流程变量测试代码:
/**
* 根据办理人查询任务并找出流程变量
*/
@Test
public void queryTaskByAssignee(){
String assignee = "employee";
List taskList = taskService.createTaskQuery()
.processDefinitionKey("activiti_leave")
.taskAssignee(assignee)
.orderByTaskCreateTime()
.desc()
.list();
Task task = taskList.get(0);
Map map = taskService.getVariables(task.getId());
System.out.println(map);
List executionList = runtimeService.createExecutionQuery()
.processDefinitionKey("activiti_leave")
.orderByProcessInstanceId()
.asc()
.list();
Execution execution = executionList.get(0);
Map map1 = runtimeService.getVariables(execution.getId());
System.out.println(map1);
}
小结: 在流程实例级别上的流程变量, 当流程任务对象所有节点都执行完成之后, 整条流程实例就已经结束了, 此时的流程变量就消失了, 也就无法再根据流程任务对象来拿流程变量了
② 流程任务级别的流程变量
/**
* 在特定的任务下放入流程变量
*/
@Test
public void setVariablesInTask(){
String assignee = "employee";
Task task = taskService.createTaskQuery()
.processDefinitionKey("activiti_leave")
.taskAssignee(assignee)
.singleResult();
// taskService.setVariable(task.getId(), "请假天数", 10);
// taskService.setVariable(task.getId(), "请假原因", "旅游");
// taskService.setVariable(task.getId(), "开始时间", new Date());
//或者采用下面的map方式
Map map = new HashMap();
map.put("请假天数", 11);
map.put("请假原因", "任性罢了");
map.put("开始时间", new Date());
taskService.setVariables(task.getId(), map);
}
/**
* 取出流程变量
*/
@Test
public void getVariablesInTask(){
String assignee = "employee";
Task task = taskService.createTaskQuery().processDefinitionKey("activiti_leave").taskAssignee(assignee).singleResult();
Integer days = (Integer) taskService.getVariable(task.getId(), "请假天数");
String reason = (String) taskService.getVariable(task.getId(), "请假原因");
Date startTime = (Date) taskService.getVariable(task.getId(), "开始时间");
System.out.println(days);
System.out.println(reason);
System.out.println(startTime);
}
还有一种通过对象的方式添加流程变量的, 具体用法跟上面差不多, 就不贴出代码了, 但是注意要在类进行序列化, 并且提供UID.
小结: 在流程任务对象级别上的流程变量, 当前任务以及之后的任务能够通过当前正在执行的对象(因为该流程变量挂载在当前正在执行的对象上)来获得到流程变量, 但是在当前任务之前的则无法获取该流程变量.
Activiti系列回顾:
Activiti工作流之简介与环境搭建
Activiti工作流之流程部署和相关操作
Activiti工作流之任务的运行/查询/完成