activiti的表结构介绍
ACT_RE :'RE’表示 repository,包含了流程定义和流程静态资源 (图片,规则,等等)。
ACT_RU:'RU’表示 runtime,包含运行时流程实例,任务,变量,异步任务。
ACT_HI: ‘HI’表示 history。 这些表包含历史数据。
ACT_GE : GE 表示 general。 通用数据。
表分类 | 表名 | 解释 |
---|---|---|
一般数据 | ||
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_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 | 运行时变量表 | |
其他 | ||
ACT_EVT_LOG | 事件日志 | |
ACT_PROCDEF_INFO | 流程定义的动态变更信息 | |
ACT_RU_DEADLETTER_JOB | 作业死信表-作业失败超过重试次数 | |
ACT_RU_TIMER_JOB | 运行时定时器作业表 | |
ACT_RU_INTEGRATION | 运行时整体表 | |
ACT_RU_SUSPENDED_JOB | 运行时作业暂停表 |
activiti的service介绍
service名称 | service作用 |
---|---|
RepositoryService | 资源管理类 |
RuntimeService | 流程运行管理类 |
TaskService | 任务管理类 |
HistoryService | 历史管理类 |
ManagerService | 引擎管理类 |
activiti的工作流运行流程
1.activiti.cfg.xml准备创建
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<!-- 配置数据源 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
<property name="url" value="jdbc:mysql://localhost:3306/activitidemo?nullCatalogMeansCurrent=true&useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"/>
</bean>
<!-- Activiti单独运行的ProcessEngine配置 -->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)-->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
2.processEngine创建
2.1.默认创建方式
将activiti.cfg.xml文件名及路径固定,且activiti.cfg.xml文件中有 processEngineConfiguration的配置:
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
2.2.一般创建方式
private static ProcessEngine processEngine = ProcessEngineConfiguration.createProcessEngineConfigurationFromResource(“activiti.cfg.xml”).buildProcessEngine();
3.流程部署查看
3.1.一般流程部署
public void testDeployment(){
//1、创建ProcessEngine
//2、获取RepositoryServcie
RepositoryService repositoryService = processEngine.getRepositoryService();
//3、使用service进行流程的部署,定义一个流程的名字,把bpmn和png部署到数据中
Deployment deploy = repositoryService.createDeployment()
.name("部署的名字")
.key("部署的key")
.addClasspathResource("BPMN资源路径")
.addClasspathResource("其他资源路径")
.deploy();
//4、输出部署信息
System.out.println("流程部署id="+deploy.getId());
System.out.println("流程部署名字="+deploy.getName());
}
3.2.zip流程部署
public void deployProcessByZip(){
//获取流程引擎
//获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//流程部署
//读取资源包文件,构造成inputStream
InputStream inputStream = this.getClass()
.getClassLoader()
// 压缩时候一次性压缩成zip格式,如果是修改后缀名方式无法加载到数据库
.getResourceAsStream("zip的资源文件路径");
//用inputStream 构造ZipInputStream
ZipInputStream zipInputStream = new ZipInputStream(inputStream);
//使用压缩包的流进行流程的部署
Deployment deploy = repositoryService.createDeployment()
.addZipInputStream(zipInputStream)
.deploy();
System.out.println("流程部署id="+deploy.getId());
System.out.println("流程部署的名称="+deploy.getName());
}
此时影响到act_re_deployment(流程部署表)、act_re_procdef(流程定义表)、act_ge_bytearray(流程资源表)。act_re_deployment和act_re_procdef一对多关系,一次部署在流程部署表生成一条记录,但一次部署可以部署多个流程定义。
3.3.流程定义查看
public void queryProcessDefinition(){
//获取引擎
//获取 Repositoryservice
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取ProcessDifinitionQuery对象
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
/*查询当前所有的流程定义 ,返回流程定义信息的集合
processDefinitionKey(流程定义Key)
orderByProcessDefinitionVersion 进行排序
desc 倒叙
list 查询出所有的内容*/
List<ProcessDefinition> definitionList = definitionQuery.processDefinitionKey(KEY)
.orderByProcessDefinitionVersion()
.desc()
.list();
//输出信息
for (ProcessDefinition processDefinition : definitionList) {
System.out.println("流程定义ID:"+processDefinition.getId());
System.out.println("流程定义名称:"+processDefinition.getName());
System.out.println("流程定义Key:"+processDefinition.getKey());
System.out.println("流程定义版本:"+processDefinition.getVersion());
System.out.println("流程部署ID:"+processDefinition.getDeploymentId());
}
}
4.流程启动
4.1.一般流程启动
public void testStartProcess(){
//1、创建ProcessEngine
//2、获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3、根据流程定义的id启动流程
ProcessInstance instance = runtimeService.startProcessInstanceByKey(“流程定义key,bpmn文件的Id”);
//4、输出内容
System.out.println("流程定义ID:"+instance.getProcessDefinitionId());
System.out.println("流程实例ID:"+instance.getId());
System.out.println("当前活动的ID:"+instance.getActivityId());
}
4.2.含有参数的流程启动
public void testStartProcess(){
//获取流程引擎
//获取RunTimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//流程变量的map
Map<String,Object> variables = new HashMap<String,Object>();
//设置流程变量
Evection evection = new Evection();
//设置出差日期
evection.setNum(3d);
// 把流程变量的pojo放入map
variables.put("evection",evection);
//设定任务的负责人
variables.put("assignee0","人员1");
variables.put("assignee1","人员2");
variables.put("assignee2","人员3");
variables.put("assignee3","人员4");
//启动流程
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(KEY, variables);
System.out.println(processInstance.getId());
}
参数信息会存放于act_ru_variable表;执行过程影响到act_hi_actinst(流程实例执行历史信息)、act_hi_identitylin(流程参与用户的历史信息)、act_hi_procinst(流程实例的历史信息)、act_hi_taskinst(流程任务的历史信息)、act_ru_execution(流程执行信息)、act_ru_identitylink(流程的正在参与用户信息)、act_ru_task(流程当前任务信息)表
4.个人任务查看和完成
public void completTask(){
//获取引擎
//获取操作任务的服务 TaskService
TaskService taskService = processEngine.getTaskService();
Task task = taskService.createTaskQuery()
.processDefinitionKey(“流程Key”)
.taskAssignee("负责人")
.singleResult();
System.out.println("流程实例id="+task.getProcessInstanceId());
System.out.println("任务Id="+task.getId());
System.out.println("任务负责人="+task.getAssignee());
System.out.println("任务名称="+task.getName());
//完成个人任务 act_ru_task任务id
taskService.complete(task.getId());
}
5.删除流程部署信息
当前的流程如果并没有完成,想要删除的话需要使用特殊方式,原理就是级联删除。删除流程是不会影响到历史表信息只影响到act_ge_bytearray、act_re_deployment、act_re_procdef
public void deleteDeployMent(){
//获取流程引擎
//通过引擎来获取 RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//通过部署id(act_ru_task表的proc_inst_id字段)来删除流程部署信息
String deploymentId = "部署Id";
// 删除已完成的流程
//repositoryService.deleteDeployment(deploymentId);
// 删除未完成的流程
repositoryService.deleteDeployment(deploymentId,true);
}
6.下载资源文件
public void getDeployment() throws IOException {
//1、得到引擎
//2、获取api,RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3、获取查询对象 ProcessDefinitionQuery查询流程定义信息
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(KEY)
.singleResult();
//4、通过流程定义信息,获取部署ID
String deploymentId = processDefinition.getDeploymentId();
//5、通过RepositoryService ,传递部署id参数,读取资源信息(png 和 bpmn)
//5.1、获取png图片的流
//从流程定义表中,获取png图片的目录和名字
String pngName = processDefinition.getDiagramResourceName();
//通过 部署id和 文件名字来获取图片的资源
InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, pngName);
//5.2、获取bpmn的流
String bpmnName = processDefinition.getResourceName();
InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, bpmnName);
//6、构造OutputStream流
File pngFile = new File("d:/evectionflow.png");
File bpmnFile = new File("d:/evectionflow.bpmn");
FileOutputStream pngOutStream = new FileOutputStream(pngFile);
FileOutputStream bpmnOutStream = new FileOutputStream(bpmnFile);
//7、输入流,输出流的转换
IOUtils.copy(pngInput,pngOutStream);
IOUtils.copy(bpmnInput,bpmnOutStream);
//8、关闭流
pngOutStream.close();
bpmnOutStream.close();
pngInput.close();
bpmnInput.close();
}
7.查看历史信息
public void findHistoryInfo(){
//获取引擎
//获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
//获取 actinst表的查询对象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
// actinst表,条件:根据 InstanceId 查询
instanceQuery.processInstanceId("17501");
//查询 actinst表,条件:根据 DefinitionId 查询
//instanceQuery.processDefinitionId("myEvection:1:15004");
//增加排序操作,orderByHistoricActivityInstanceStartTime 根据开始时间排序 asc 升序
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//查询所有内容
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
//输出
for (HistoricActivityInstance hi : activityInstanceList) {
System.out.println(hi.getActivityId());
System.out.println(hi.getActivityName());
System.out.println(hi.getProcessDefinitionId());
System.out.println(hi.getProcessInstanceId());
System.out.println("<==========================>");
}
}
8.流程实例的挂起和激活
8.1.全部流程实例的挂起和激活
public void suspendAllProcessInstance(){
//1、获取流程引擎
//2、获取Repositoryservice
RepositoryService repositoryService = processEngine.getRepositoryService();
//3、查询流程定义,获取流程定义的查询对象
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey(“流程定义Key,bpmn文件Id”)
.singleResult();
//4、获取当前流程定义的实例是否都是挂起状态
boolean suspended = processDefinition.isSuspended();
//5、获取流程定义的id
String definitionId = processDefinition.getId();
//6、如果是挂起状态,改为激活状态
if(suspended){
//如果是挂起,可以执行激活的操作,参数1:流程定义id 参数2:是否激活,参数3:激活时间
repositoryService.activateProcessDefinitionById(definitionId,
true,
null);
System.out.println("流程定义id:"+definitionId+",已激活");
}else {
//7、如果是激活状态,改为挂起状态,参数1:流程定义id 参数2:是否暂停 参数3 :暂停的时间
repositoryService.suspendProcessDefinitionById(definitionId,
true,
null);
System.out.println("流程定义id:"+definitionId+",已挂起");
}
}
8.2.单个流程实例的挂起和激活
public void suspendSingleProcessInstance(){
//1、获取流程引擎
//2、RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3、通过RuntimeService获取流程实例对象
ProcessInstance instance = runtimeService.createProcessInstanceQuery()
.processInstanceId("流程实例Id")
.singleResult();
//4、得到当前流程实例的暂停状态,true-已暂停 false -激活
boolean suspended = instance.isSuspended();
//5、获取流程实例id
String instanceId = instance.getId();
//6、判断是否已经暂停,如果已经暂停,就执行激活操作
if(suspended){
//如果已经暂停,就执行激活
runtimeService.activateProcessInstanceById(instanceId);
System.out.println("流程实例id:"+instanceId+"已经激活");
}else {
//7、如果是激活状态,就执行暂停操作
runtimeService.suspendProcessInstanceById(instanceId);
System.out.println("流程实例id:"+instanceId+"已经暂停");
9.任务组操作
如果流程节点存在多个人员能处理,这时我们无法直接定义处理人员需要引入任务组概念来进行处理。
9.1.任务组查询
act_ru_identitylink
记录当前参考任务用户或组,当前任务如果设置了候选人,会向该表插入候选人记录,有几个候选就插入几个。查询数据本质来源是act_ru_task
表,由于该任务当前是组任务,此时所有assignee为空,所以会查不到数据。
public void findGroupTaskList(){
//任务候选人
String candidateUser = "人员1";
//获取引擎
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//查询组任务
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey(KEY)
.taskCandidateUser(candidateUser) //根据候选人查询任务
.list();
for (Task task : taskList) {
System.out.println("========================");
System.out.println("流程实例ID="+task.getProcessInstanceId());
System.out.println("任务id="+task.getId());
System.out.println("任务负责人="+task.getAssignee());
}
}
9.2.候选人拾取任务
public void claimTask(){
//获取引擎
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//当前任务的id
String taskId = "65002";
//任务候选人
String candidateUser = "候选人员";
//查询任务
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskCandidateUser(candidateUser)
.singleResult();
if(task != null){
//拾取任务
taskService.claim(taskId,candidateUser);
System.out.println("taskid-"+taskId+"-用户-"+candidateUser+"-拾取任务完成");
}
}
候选人完成拾取之后就可以查到任务。
9.3.任务的归还
public void testAssigneeToGroupTask(){
//获取引擎
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//当前任务的id
String taskId = "65002";
//任务负责人
String assignee = "候选人员";
//根据key 和负责人来查询任务
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskAssignee(assignee)
.singleResult();
if(task != null){
// 归还任务 ,就是把负责人设置为空
taskService.setAssignee(taskId,null);
System.out.println("taskid-"+taskId+"-归还任务完成");
}
}
任务一旦归还那么候选人查询时候就无法查出任务
9.4.任务的交接
public void testAssigneeToCandidateUser(){
//获取引擎
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//当前任务的id
String taskId = "65002";
//任务负责人
String assignee = "候选人员1";
//任务候选人
String candidateUser = "候选人员2";
//根据key 和负责人来查询任务
Task task = taskService.createTaskQuery()
.taskId(taskId)
.taskAssignee(assignee)
.singleResult();
if(task != null){
//交接任务 ,就是把负责人 设置为空
taskService.setAssignee(taskId,candidateUser);
System.out.println("taskid-"+taskId+"-交接任务完成");
}
}
后记
本章内容参考视频: https://www.bilibili.com/video/BV1H54y167gf?from=search&seid=15272098582557659119
Github地址:https://github.com/charonry/activiti