我们今天分享activiti 集成 springBoot 配置入门使用,入门是关键 也是我们成为大牛的必经之路,废话少说,上:
一、配置启动初始化
1、pom文件引入
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<version>7.1.0.M6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
2、数据库配置
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver #mysql 8.XX版本额驱动
url: jdbc:mysql://16.2.8.1:3306/activiti?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&nullCatalogMeansCurrent=true
username: root
password: 't6n?_'
activiti:
check-process-definitions: true #自动检查、部署流程定义文件
#1.flase:默认值。activiti在启动时,对比数据库表中保存的版本,如果没有表或者版本不匹配,将抛出异常
#2.true: activiti会对数据库中所有表进行更新操作。如果表不存在,则自动创建
#3.create_drop: 在activiti启动时创建表,在关闭时删除表(必须手动关闭引擎,才能删除表)
#4.drop-create: 在activiti启动时删除原来的旧表,然后在创建新表(不需要手动关闭引擎)
database-schema-update: true
#activiti7默认不生成历史信息表,开启历史表
db-history-used: true
#记录历史等级 可配置的历史级别有none, activity, audit, full
#none:不保存任何的历史数据,因此,在流程执行过程中,这是最高效的。
#activity:级别高于none,保存流程实例与流程行为,其他数据不保存。
#audit:除activity级别会保存的数据外,还会保存全部的流程任务及其属性。audit为history的默认值。
#full:保存历史数据的最高级别,除了会保存audit级别的数据外,还会保存其他全部流程相关的细节数据,包括一些流程参数等。
history-level: full
注意:如果配置的是8以上版本驱动,而你的数据库是5.7 ,你需要在数据库连接后面加上:
&nullCatalogMeansCurrent=true
如果不加可能报错:
Cause: java.sql.SQLSyntaxErrorException: Table ‘myactiviti.act_ge_property‘ doesn‘t exist
原因:
因为mysql使用schema标识库名而不是catalog,因此mysql会扫描所有的库来找表,如果其他库中有相同名称的表,activiti就以为找到了,本质上这个表在当前数据库中并不存在。
设置nullCatalogMeansCurrent=true,表示mysql默认当前数据库操作,在mysql-connector-java 5版本该参数默认为true,6版本以上默认为false,因此8版本驱动需要设置nullCatalogMeansCurrent=true。
3、bpmn 文件生成
先简单参考,此处仅贴出业务工作流图:
4、服务启动初始化脚本25张表
@SpringBootApplication
public class ActivitiApplication {
public static void main(String[] args) {
SpringApplication.run(ActivitiApplication.class,args);
}
}
结果如下图:
服务启动后、整个部署过程操作了四张数据表:
act_ge_bytearray 流程资源表 ,每个流程定义对应两个资源记录,bpmn和png。
act_ge_property 参数配置表
act_re_deployment 流程定义部署表,每部署一次增加一条记录
act_re_procdef 流程定义表,部署每个新的流程定义都会在这张表中增加一条记录。记录中的key就是流程定义中最为重要的字段。
验证下面流程!
二、测试验证流程
1、 启动工作流
@Test
public void testStart(){
ProcessInstance processInstance = runtimeService
.startProcessInstanceByKey("myTestAct");
System.out.println("流程定义id:" + processInstance.getProcessDefinitionId());
System.out.println("流程实例id:" + processInstance.getId());
System.out.println("当前活动Id:" + processInstance.getActivityId());
}
执行结果打印日志:
流程定义id:myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
当前活动Id:null
此次操作涉及到几张日志表:
act_hi_actinst 流程实例执行历史
act_hi_identitylink 流程的参与用户历史信息
act_hi_procinst 流程实例历史信息
act_hi_taskinst 流程任务历史信息
act_ru_execution 流程执行信息
act_ru_identitylink 流程的参与用户信息
act_ru_task 任务信息
2、查询当前人待执行的任务
@Test
public void testFindPersonalTasks() {
// 任务负责人
String assignee = "appler";
// String assignee = "leader";
// 根据流程key 和 任务负责人 查询任务
List<Task> list = taskService.createTaskQuery()
.processDefinitionKey("myTestAct") //流程Key
.taskAssignee(assignee)//只查询该任务负责人的任务
.list();
for (Task task : list) {
System.out.println("流程实例id:" + task.getProcessInstanceId());
System.out.println("任务id:" + task.getId());
System.out.println("任务负责人:" + task.getAssignee());
System.out.println("任务名称:" + task.getName());
}
}
查询结果日志:
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
任务id:791a5174-c319-11ed-9c09-9a473ddfa0cf
任务负责人:appler
任务名称:请假申请
注意:工作流启动后,首先只有appler下会有任务(如上),如果此时你查leader、hrbp 下面是没有任务的;只有appler下的任务执行完成之后,流程才进入到leader下面;同理leader下的任务执行之后,会流到hrbp下面,这就是工作流的精髓所在!
3、提交完成任务
@Test
public void testCompletTask(){
/**
* 根据流程key 和 任务的负责人 查询任务
* 返回一个任务对象
*/
Task task = taskService.createTaskQuery()
.processDefinitionKey("myTestAct") //流程Key
.taskAssignee("appler") //要查询的负责人
.singleResult();
System.out.println("流程实例id:" + task.getProcessInstanceId());
System.out.println("任务id:" + task.getId());
System.out.println("任务负责人:" + task.getAssignee());
System.out.println("任务名称:" + task.getName());
taskService.complete(task.getId());//提交完成任务,参数:任务id
}
执行后日志
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
任务id:791a5174-c319-11ed-9c09-9a473ddfa0cf
任务负责人:appler
任务名称:请假申请
注意:此时appler 提交执行完了,就可以查询并提交leader下面的任务了!
4、查询出当前所有的流程定义
@Test
public void testQueryDefinition(){
//得到ProcessDefinitionQuery 对象
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//条件:processDefinitionKey =myTestAct
List<ProcessDefinition> definitionList = processDefinitionQuery.processDefinitionKey("myTestAct")
.orderByProcessDefinitionVersion()//orderByProcessDefinitionVersion 按照版本排序
.desc()//desc倒叙
.list();//返回集合
for (ProcessDefinition processDefinition : definitionList) { //输出流程定义信息
System.out.println("流程定义 id="+processDefinition.getId());
System.out.println("流程定义 name="+processDefinition.getName());
System.out.println("流程定义 key="+processDefinition.getKey());
System.out.println("流程定义 Version="+processDefinition.getVersion());
System.out.println("流程部署ID ="+processDefinition.getDeploymentId());
}
}
结果日志
流程定义 id=myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
流程定义 name=员工请假审批流程
流程定义 key=myTestAct
流程定义 Version=1
流程部署ID =f40d7fb6-c318-11ed-bd79-9a473ddfa0cf
此时只有一个流程正在执行,正常情况在可能有多个流程同时执行!
5、查询某个流程实例状态
@Test
public void testQueryProcess() {
String processDefinitionKey = "myTestAct";
List<ProcessInstance> list = runtimeService
.createProcessInstanceQuery()
.processDefinitionKey(processDefinitionKey)//
.list();
for (ProcessInstance processInstance : list) {
System.out.println("流程实例id:" + processInstance.getProcessInstanceId());
System.out.println("所属流程定义id:" + processInstance.getProcessDefinitionId());
System.out.println("是否执行完成:" + processInstance.isEnded());
System.out.println("是否暂停:" + processInstance.isSuspended());
System.out.println("当前活动标识:" + processInstance.getActivityId());
System.out.println("业务关键字:"+processInstance.getBusinessKey());
}
}
结果日志
流程实例id:79156f70-c319-11ed-9c09-9a473ddfa0cf
所属流程定义id:myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
是否执行完成:false
是否暂停:false
当前活动标识:null
业务关键字:null
6、删除某个流程记录
@Test
public void testDeleteDeployment() {
// 流程部署id
String deploymentId = "70302f48-c2f7-11ed-9448-9a473ddfa0cf";
//删除流程定义,如果该流程定义已有流程实例启动则删除时出错
repositoryService.deleteDeployment(deploymentId);
//设置true 级联删除流程定义,即使该流程有流程实例启动也可以删除,设置为false非级别删除方式,如果流程
//repositoryService.deleteDeployment(deploymentId, true);
}
对应 act_re_deployment 张表里的数据,可以查询看看。
注意:
1)、这里只删除了流程定义,不会删除历史表信息
2)、删除任务时,可以选择传入一个boolean型的变量cascade ,表示是否级联删除。默认是false,表示普通删除。如果该流程下存在已经运行的流程,使用普通删除会报错,而级联删除可以将流程及相关记录全部删除。删除没有完成的流程节点后,就可以完全删除流程定义信息了。项目开发中,级联删除操作一般只开放给超级管理员使用。
7、查看历史信息(已经结束的流程)
@Test
public void testFindHistory(){
//获取 actinst表的查询对象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//查询 actinst表,条件:根据 InstanceId 查询,查询一个流程的所有历史信息
instanceQuery.processInstanceId("79156f70-c319-11ed-9c09-9a473ddfa0cf");
// .activityType("serviceTask")
instanceQuery.finished();
//查询 actinst表,条件:根据 DefinitionId 查询,查询一种流程的所有历史信息
//增加排序操作,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());
}
}
结果日志
_2
StartEvent
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_3
请假申请
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_4
总监审批
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_5
人事审批
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
_6
EndEvent
myTestAct:1:f4294519-c318-11ed-bd79-9a473ddfa0cf
79156f70-c319-11ed-9c09-9a473ddfa0cf
注意:
1)、关于流程历史信息,要注意,在删除流程时,如果是采取级联删除的方式,那这个历史信息也会随着一起删除。而普通删除方式不会删除历史信息。
2)、历史信息有不同的种类,具体可以通过historyService构建不同类型的Query对象来获取结果。
到此、初级操作分享完成,后期我们分享其高级功能,敬请期待!