processEngine是Activiti的工作核心,负责生成流程运动时的各种实例与数据。
一共涉及23张表,所有表都已ACT_开头。
ACT_RE_*:repository,包含流程定义和流程静态资源。
ACT_RU_*:runtime,运行时的表,包含实例、任务、变量、异步任务等运行时的数据。流程结束后会删除。
ACT_ID_*:identity,包含身份信息。
ACT_HI_*:history,包含历史数据,历史流程实例。
ACT_GE_*:通用数据,如资源文件。
ProcessEngineConfiguration configuration = ProcessEngineConfiguration
.createStandaloneProcessEngineConfiguration();//静态方法,相当于new单例的StandaloneProcessEngineConfiguration()
configuration.setJdbcDriver("com.mysql.jdbc.Driver");
configuration.setJdbcUrl("jdbc:mysql://localhost:3306/activiti_demo?useUnicode=true&characterEncoding=utf8");
configuration.setJdbcUsername("xxx");
configuration.setJdbcPassword("xxx");
/*
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";自动创建表
*/
configuration.setDatabaseSchemaUpdate(configuration.DB_SCHEMA_UPDATE_TRUE);
ProcessEngine processEngine = configuration.buildProcessEngine();// 创建表
ProcessEngineConfiguration resource = ProcessEngineConfiguration
.createProcessEngineConfigurationFromResource("activiti.cfg.xml");
ProcessEngine buildProcessEngine = resource.buildProcessEngine();
// 1.得到流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine(); // 默认加载classpath下activiti.cfg.xml文件
// 2.调用管理与部署的service
RepositoryService repositoryService = processEngine.getRepositoryService(); // 流程定义与部署对象相关的service
// 3.创建一个部署对象
repositoryService.createDeployment().name("helloword")
// 4.加载资源文件
.addClasspathResource("diagrams/helloword.bpmn") // 加载bpmn文件
.addClasspathResource("diagrams/helloword.png") // 加载png文件
// 部署
.deploy();
流程引擎相同。
// 利用流程引擎得到servic
processEngine.getRuntimeService()
// 启动
.startProcessInstanceByKey(processDefinitionKey); // 会返回ProcessInstance对象
注:使用流程定义的key启动,key对应的是.bpmn文件的id值。使用key启动可以自动的找到最新版本的流程实例进行启动(如果,同一个流程启动两次,那么版本就会叠加)。
流程引擎相同。
// 利用流程引擎得到service
processEngine.getTaskService()
// 创建任务查询对象
.createTaskQuery()
// 指定查询条件
.taskAssignee("张三") // 根据代办人查询
// 返回结果集
.list(); // 需用list接收
act_re_deployment:部署对象表
act_re_procdef:流程定义表
act_ge_bytearray:资源文件表
act_ge_property:主键生成策略表
/**
* zip部署
*/
public void deployProcessDefinition() {
InputStream resourceAsStream = this.getClass().getClassLoader().getResourceAsStream("diagrams/helloword.zip");
ZipInputStream zipInputStream = new ZipInputStream(resourceAsStream);
Deployment deployment = processEngine.getRepositoryService()
.createDeployment()
.name("请假流程demo")
.addZipInputStream(zipInputStream)
.deploy();// 部署
System.out.println("部署ID:"+deployment.getId());
System.out.println("部署名称:"+deployment.getName());
}
// 实例流程引擎获取service,然后删除
processEngine.getRepositoryService().deleteDeployment("15001", true);
注:带有true是级联删除。反之只能删除没有启动的流程。
/**
* 获取资源文件
* @throws IOException
*/
@Test
public void viewPic() throws IOException {
List list = processEngine.getRepositoryService()
.getDeploymentResourceNames("1");// 根据id来获取名称,得到一个集合
// 得到png文件的名称
String resourceName = "";
for (String name : list) {
if(name.indexOf(".png")>0) {
resourceName = name;
}
}
// 获取数据流
InputStream inputStream = processEngine.getRepositoryService()
.getResourceAsStream("1", resourceName);
// 利用org.apache.commons.io.FileUtils来完成写入
FileUtils.copyInputStreamToFile(inputStream, new File("D:"+File.separator+resourceName));
}
问:查看最新的流程实例
思路:先查询出所有的流程实例,根据版本asc排序(最高版本就会在最底下)。把流程定义装进map中,key值设置为流程定义的key,value为流程定义对象(因为map有这个特性,会过替换掉key相同的,故只留下了最新的版本)。最后value转成list就行了。
代码实现如下:
/**
* 查询最新的流程定义
*/
public void findLastVersionProcessDefinition() {
List lists = processEngine.getRepositoryService()
.createProcessDefinitionQuery()
.orderByProcessDefinitionVersion()
.asc()
.list();
Map map = new LinkedHashMap<>();
if(lists.size()>0) {
for (ProcessDefinition list : lists) {
map.put(list.getKey(), list);
}
}
List pdlist = new ArrayList<>(map.values());
for (ProcessDefinition list : pdlist) {
System.out.println("流程定义的ID:"+list.getId());
System.out.println("流程定义的名称:"+list.getName());
System.out.println("流程定义的key:"+list.getKey());
System.out.println("流程定义的version:"+list.getVersion());
}
}
ru表示正在执行的表
act_ru_axcution正在执行的对象表
1.如果是单例流程(没有分值的聚合),那么流程实例ID(ID_),和对象ID相同(reoc_inst_id_).
2.一个流程实例只有一个,执行对象可以有多个(存在分支和聚合的情况下)
具体的启动操作参见前面的初体验部分
查询参看taskservice部分
关于的四张表:
act_hi_procinst:流程实例历史表
act_ru_task:正在执行的任务表(只有带节点是user_task的时候,该表中存在数据)
act_hi_taskinst:任务历史表
act_hi_actinst:所有活动的节点
/**
* 查询个人任务
*/
public void findMyPersonTask() {
List list = processEngine.getTaskService() // 得到对应的service
.createTaskQuery() // 创建任务查询对象
.taskAssignee("张三") // 根据代办人条件查询,相当于sql中的where
.orderByTaskCreateTime() // 设置排序条件,可以设置多个
.asc() // 排序
.list(); // 返回的结果集,有list()、count()、singleResult()等
}
processEngine.getTaskService()
.complete("42502"); // 根据id来完成
作用于一个流程实例。
act_ru_variable:正在执行的变量
act_hi_variable:你是流程变量表
获取变量同设置
/**
* 设置流程变量
*/
public void setVariables() {
TaskService taskService = processEngine.getTaskService();
// 设置任务ID
String taskid = "37504";
taskService.setVariableLocal(taskid, "请假天数", 3);
taskService.setVariable(taskid, "请假日期", new Date());
taskService.setVariable(taskid, "请假原因", "回家探亲");
}
/**
* 获取流程变量
*/
public void getVariables() {
TaskService taskService = processEngine.getTaskService();
// 设置任务ID
String taskid = "42502";
Integer days = (Integer) taskService.getVariable(taskid, "请假天数");
Object date = taskService.getVariable(taskid, "请假日期");
String yuanyin = (String) taskService.getVariable(taskid, "请假原因");
System.out.println("请假天数:"+days+"===请假日期:"+date+"===请假原因:"+yuanyin);
}
注:
.setVariable和.setVariableLocal的区别:
第二个是与该节点试行绑定,到下一个就看不到。反之就是不绑定。
需要序列化。会存到act_ge_bytearray(资源表)
javabean:
public class Person implements Serializable{
/**
* javabean
*/
private static final long serialVersionUID = 1L; // 设置版本号
public Person() {
}
public Person(String id, String name) {
this.id = id;
this.name = name;
}
private String id;
private String name;
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
设置变量:
/**
* 设置流程变量
*/
public void setVariables() {
TaskService taskService = processEngine.getTaskService();
// 设置任务ID
String taskid = "37504";
taskService.setVariable(taskid, "人员信息", new Person(UUID.randomUUID().toString(),"张狗子"));
}
取流程变量:
/**
* 获取流程变量
*/
public void getVariables() {
TaskService taskService = processEngine.getTaskService();
// 设置任务ID
String taskid = "42502";
Person person = (Person) taskService.getVariable(taskid, "人员信息");
System.out.println("ID:"+person.getId()+"===name:"+person.getName());
}
解决:可在javabean中设置版本号。也就是:
private static final long serialVersionUID = 1L; // 设置版本号
查询的套路
/**
* 流程实例查询
*/
public void findHistoryProcessInstance() {
processEngine.getHistoryService()
.createHistoricProcessInstanceQuery()
.processInstanceId("")
.list();
}
.createHistoricProcessInstanceQuery() // 历史流程实例查询
.createHistoricActivitiInstanceQuery() // 历史活动实例查询
.createHistoricTaskInstanceQuery() // 历史任务实例查询
.createHistoricVariableInstanceQuery() // 历史变量实例查询
在MainConfig中codition添加判断,使用${}或者#{}
所以在完成任务时需要加上流程变量。
processEngine.getTaskService().complete(taskId, variables);
解释:所有条件都不符合的时候走一个分支
办理人使用流程变量${__}或者#{__},启动时:
processEngine.getRuntimeService()
.startProcessInstanceByKey(key,设置变量);
2.1类实现TaskListener接口
2.2重写notify方法
2.3设置值。delegateTask.setAssignee("xxx");
2.4在Listeners找到并选中该类。
最后启动即可成功。
在main config下的Candidate users 直接指定。
processEngine.getTaskService()
.createTaskQuery()
.taskCandidateUser("xxx"); // 组任务查询正在执行的任务办理人
processEngine.getTaskService()
.getIdentityLinksForTask(taskid)
processEngine.getTaskService()
.claim(taskId, userId);
思路:
把Assignee置为空。
processEngine.getTaskService()
.setAssignee(taskId, null);
processEngine.getTaskService()
.addCandidateUser(taskId, userId); // 添加
.deleteCandidateUser(taskId, userId); // 删除
map.put("变量","添加组")
雷同个人任务分配。
存放表在act_ru_identitylink、act_hi_identitylink
个人任务与组任务的区别:
个人任务的type为participant(参与者),但组任务为candidate(候选者)