Hello,大家好,我是你们的CodeWorld,今天抽空写了这么一篇Activiti的基本使用,上一届我们对Activiti进行了入门教学,那么我们今天就开始下一节的讲解,相信你会有很多的收获。
我们可以通过如下方式来安装插件,首先选中Plugins然后选中Install Plugin from Disk,然后再从硬盘里面加载对应的jar包,这个jar包可以直接从这里下载
bpmn插件
这里我就不用去多说了吧,我相信都会一键创建SpringBoot项目
<!--引入Activiti和springboot整合的依赖-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring-boot-starter</artifactId>
<!--此处必须用M2版本的,否则必须强制使用SpringSecurity来做用户认证-->
<version>7.1.0.M2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.45</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.6.6</version>
</dependency>
引入以上的依赖信息
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/activiti?characterEncoding=utf8&zeroDateTimeBehavior=convertToNull
username: root
password: root
driver-class-name: com.mysql.jdbc.Driver
activiti:
check-process-definitions: false
db-history-used: true
jpa:
hibernate:
ddl-auto: create
show-sql: true
server:
port: 8002
我们需要去创建一个activiti这个数据库,不然找不到数据库
看来我们的引擎对象已获取到了
那么我们再来看看数据库中是否已经创建好表结构了
果不其然,表结构已经创建好了,
我们可以看到这25张表都是以act开头的。
然后中间部分重点说一下:
具体的每张表的含义,可以看下表:
表分类 | 表名称 | 描述 |
---|---|---|
一般数据 | 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_ID_GROUP | 身份信息-组信息 |
ACT_ID_INFO | 身份信息-组信息 | |
ACT_ID_MEMBERSHIP | 身份信息-用户和组关系的中间表 | |
ACT_ID_USER | 身份信息-用户信息 | |
流程定义表 | 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 | 运行时变量表 |
这里我们就对activiti的数据库介绍就到这里了,那么接下来就开始实战练习了
我们需要在resources下面新建一个example.bpmn的文件,并将流程图画好如下
然后我们去写一个测试类来启动我们的流程
/**
* 部署流程
*/
@Test
public void testCreateProcess(){
Deployment examineDeployment = repositoryService.createDeployment()
.name("审批实例流程")
.addClasspathResource("example.bpmn")
.deploy();
log.info("流程部署Id=" + examineDeployment.getId());
log.info("流程部署名字" + examineDeployment.getName());
}
我们从这个表里面看见一个 Key(后面会讲,这个很重要),我们现在需要通过这个key来查询流程的定义
/**
* 查询流程定义
*/
@Test
public void testSelectProcess() {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//获取流程定义查询器
ProcessDefinitionQuery processDefinitionQuery = repositoryService.createProcessDefinitionQuery();
//通过key查询对应的流程定义,返回的是满足条件的一个List
List processDefinitions = processDefinitionQuery.processDefinitionKey("myProcess_1")
.orderByProcessDefinitionVersion()//同样的key可能查询出来的流程定义有多个,这个时候我们需要通过定义的版本倒叙排列一下。
.desc()
.list();
for (ProcessDefinition processDefinition : processDefinitions) {
log.info("流程定义Id:" + processDefinition.getId());
log.info("流程定义Key:" + processDefinition.getKey());
log.info("流程定义Version:" + processDefinition.getVersion());
log.info("流程定义Name:" + processDefinition.getName());
}
}
运行结果
如果我们再次执行部署流程的测试代码
并且我们发现这是两个不同的流程,但是他们的key是默认相同的
这样我们就会发现同一个key定义了不同的流程,同样的key可能查询出来的流程定义有多个,这个时候我们需要通过定义的版本倒叙排列一下。
不过有个问题,我们的最终会一个流程一个key,那么多个流程的话,我们最终也只会使用最新的那个流程,那么我们上述的查询方法就会有问题,所以我们改用以下方式来查询
/**
* 删除流程
*/
@Test
public void testDeleteProcess() {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//这里定义流程部署的Id
String deploymentId = "67199f40-5d72-11ec-8eee-764ca19a8e09";
//删除流程部署信息,这个时候会把部署信息和对应的流程定义一并删除
repositoryService.deleteDeployment(deploymentId);
}
我们去看看我们的数据库,是否还存在该流程(67199f40-5d72-11ec-8eee-764ca19a8e09)
但是这里要注意,我们虽然吧流程给删除了,但是流程中历史信息不会被删除
后面我们会继续试验
问题来了:
删除流行定义的时候,可能会遇到如下的坑,就是如果我们有流程已经启动了,并且还没有执行完成,正在这个时候,如果我们删除其对应的流程定义是无法删除的。我们可以试试看发现抛异常了。那么如果领导要求我们必须非得要删除怎么办?这个时候,我们的做法应该是删除流程定义的时候,同时把对应的正在进行中的流程实例数据一并删除。
我们只需要将这个方法加一个true
repositoryService.deleteDeployment(deploymentId,true);
/**
* 流程历史记录信息查看
*/
@Test
public void testSelectHistoryProcess() {
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
//获取历史流程实例查询对象
HistoricProcessInstanceQuery historicProcessInstanceQuery = historyService.createHistoricProcessInstanceQuery();
//获取历史流程实例
List historicProcessInstances = historicProcessInstanceQuery.deploymentId("eac62be3-5d77-11ec-a7ac-764ca19a8e09").orderByProcessInstanceStartTime().desc().list();
historicProcessInstances.forEach(historicProcessInstance -> {
log.info("流程Id是:" + historicProcessInstance.getId());
log.info("流程定义名称是:" + historicProcessInstance.getProcessDefinitionName());
log.info("流程开始时间:" + historicProcessInstance.getStartTime());
log.info("流程结束时间:" + historicProcessInstance.getEndTime());
});
}
/**
* 获取历史流程数据活动记录
*/
@Test
public void testSelectProcessDetail(){
//获取流程引擎
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
//获取历史的活动实例的查询对象
HistoricActivityInstanceQuery historicActivityInstanceQuery = historyService.createHistoricActivityInstanceQuery();
//获取历史的对应流程实例信息流转数据
List activityInstances = historicActivityInstanceQuery.processInstanceId("eac62be3-5d77-11ec-a7ac-764ca19a8e09").list();
for (HistoricActivityInstance activityInstance : activityInstances) {
log.info("Id:" + activityInstance.getId());
log.info("节点名称:" + activityInstance.getActivityName());
log.info("对应的流程实例Id:" + activityInstance.getProcessInstanceId());
log.info("对应的流程定义Id:" + activityInstance.getProcessDefinitionId());
}
}
以上我们就对流程的相关的知识点做了基本的讲述,满满的干货,接下来就会讲解任务执行了
好了,本次的技术解析就到这里了?如果觉得不错的话,点亮一下小星星codeworld-cloud-shop 只看不点,不是好孩子哦!!