目录
1. 什么是工作流?
工作流(Workflow):就是通过计算机对业务流程自动化执行管理。主要解决多个参与者之间按照某种预定义的规则自动进行传递文档、信息或任务的过程,从而达到预期的目标。
具体应用:
关键业务:订单、报价处理、合同审核、客户电话处理、供应链管理
行政管理:出差申请、加班申请、请假申请等
人事管理:员工安排、绩效考评
财务类:付款请求等
客户服务类:客户信息管理、客户投诉等
2. 什么是Activiti?
2.1 相关概念
BPM(Business Process Management):业务流程管理,是一种规范化的构造端的业务流程,持续提高组织业务效率。
BPMN软件:
BPMN(Business Process Model AndNotation):业务流程模型和符号。
2.2 activiti使用步骤
- 部署activiti
- 使用流程建模工具定义业务流程
- activiti部署业务流程定义
- 启动流程实例
- 用户查询待办任务
- 用户办理任务
- 流程结束
2.3 activiti开发环境
安装activiti bpmn插件:
如果找不到idea中bpmn插件需要自己手动添加,如果有小伙伴怕麻烦,在这里准备资源可以自取链接:
链接:https://pan.baidu.com/s/1zSHNO-ZKxydJcbzG-Au4Yw?pwd=efsu
提取码:efsu
2.4 service的功能介绍
service名称 | service作用 |
RepositoryService | activiti的资源管理类 |
RuntimeService | activiti的流程运行管理类 |
TaskService | activiti的任务管理类 |
HistoryService | activiti的历史管理类 |
ManagementService | activiti的引擎管理类 |
3 快速入门
引入pom.xml:
<properties>
<slf4j.version>1.6.6</slf4j.version>
<log4j.version>1.2.12</log4j.version>
<activiti.version>6.0.0</activiti.version>
</properties>
<dependencies>
<!--activiti引擎依赖-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>${activiti.version}</version>
</dependency>
<!--spring整合activiti-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>${activiti.version}</version>
</dependency>
<!--activiti的bpmn的模型处理-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-model</artifactId>
<version>${activiti.version}</version>
</dependency>
<!--activiti的bpmn的转换-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!--json数据转换-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-json-converter</artifactId>
<version>${activiti.version}</version>
</dependency>
<!--activiti的bpmn布局-->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-bpmn-layout</artifactId>
<version>${activiti.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.20</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.4</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>${log4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
</dependencies>
日志文件log4j.properties:
# Set root category priority to INFO and its only appender to CONSOLE.
#log4j.rootCategory=INFO, CONSOLE debug info warn error fatal
log4j.rootCategory=debug, CONSOLE, LOGFILE
# Set the enterprise logger category to FATAL and its only appender to CONSOLE.
log4j.logger.org.apache.axis.enterprise=FATAL, CONSOLE
# CONSOLE is set to be a ConsoleAppender using a PatternLayout.
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
# LOGFILE is set to be a File appender using a PatternLayout.
# log4j.appender.LOGFILE=org.apache.log4j.FileAppender
# log4j.appender.LOGFILE.File=d:\axis.log
# log4j.appender.LOGFILE.Append=true
# log4j.appender.LOGFILE.layout=org.apache.log4j.PatternLayout
# log4j.appender.LOGFILE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
activiti的配置文件activiti.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--默认方式下固定processEngineConfiguration-->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!--配置数据源信息-->
<property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti?serverTimezone=Asia/Shanghai"/>
<property name="jdbcUsername" value="root"/>
<property name="jdbcPassword" value="root"/>
<!--activiti在生成表时的策略,如果已经存在表就直接使用否则创建表-->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
测试类:
/**
* 使用activiti默认创建mysql表
*/
@Test
public void activitiCreateTable(){
//使用activiti提供的工具类
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
System.out.println("========processEngine=======>"+processEngine);
}
程序运行:
3.1 activiti生成的表结构
act_re 流程定义和流程资源
act_ru 运行时,流程实例、任务、变量
act_hi 历史表
act_ge 通用表
3.2 activiti的体系架构
类关系图:
3.2.1流程引擎配置
流程引擎配置类activiti.cfg.xml:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--配置方式二:使用连接池dbcp的方式配置相关信息-->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/activiti?serverTimezone=Asia/Shanghai" />
<property name="username" value="root" />
<property name="password" value="root" />
<property name="maxActive" value="3" />
<property name="maxIdle" value="1" />
</bean>
<!--配置方式一:默认方式下固定processEngineConfiguration-->
<bean id="processEngineConfiguration" class="org.activiti.engine.impl.cfg.StandaloneProcessEngineConfiguration">
<!--配置数据源信息-->
<!--<property name="jdbcDriver" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/activiti?serverTimezone=Asia/Shanghai"/>
<property name="jdbcUsername" value="root"/>
<property name="jdbcPassword" value="root"/>-->
<!--引用连接池信息-->
<property name="dataSource" ref="dataSource" />
<!--activiti在生成表时的策略,如果已经存在表就直接使用否则创建表-->
<property name="databaseSchemaUpdate" value="true"/>
</bean>
</beans>
ActivitiCreateTableTest测试类:
@Test
public void activitiCreateTable(){
//使用activiti提供的工具类
// ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
/* RepositoryService repositoryService = processEngine.getRepositoryService();
repositoryService.createProcessDefinitionQuery();*/
ProcessEngineConfiguration processEngineConfigurationFromResource = ProcessEngineConfiguration.
createProcessEngineConfigurationFromResource("activiti.cfg.xml", "processEngineConfiguration");
//获取流程引擎对象
ProcessEngine processEngine = processEngineConfigurationFromResource.buildProcessEngine();
System.out.println("========processEngine=======>"+processEngine);
}
4. activiti的入门案例详解
创建activiti的工作流的步骤:
1. 定义流程:按照bpmn规范,使用流程定义工具,用流程符号把整个流程描述出来。
2. 部署流程:把画好的流程定义文件,加载到数据库中,生成表的数据。
3. 启动流程:用java代码操作数据库。
evection.bpmn文件转为evection.xml中文乱码解决:
4.1 流程符号
事件Event:
活动Activity:
网关GateWay:
流向Flow:
流程设计器的使用:
.bpmn文件本质上是xml文件。
生成png文件:
流程部署:
@Test
public void testProcessDeploy(){
//1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3. 使用service进行流程的部署,定义一个流程名字,把bpmn和png部署到数据库中
Deployment deploy = repositoryService.createDeployment()
.name("个人出差申请流程")
.addClasspathResource("bpmn/evection.bpmn")
.addClasspathResource("bpmn/evection.png")
.deploy();
System.out.println("========流程部署id=======>"+deploy.getId());
System.out.println("=======流程部署名字=========>"+deploy.getName());
}
测试运行:
--
ACT_GE_PROPERTY update
-- 流程定义表
ACT_RE_PROCDEF insert
-- 流程部署表:每部署一次增加一条记录
ACT_RE_DEPLOYMENT insert
-- 流程资源表
ACT_GE_BYTEARRAY insert
流程定义部署:
1. 使用流程设计器,使用流程符号,画出流程图。
bpmn文件 -- > png文件
都是流程资源文件,用来描述流程,流程中的需要的节点,节点负责人
出差申请流程,请假申请流程、报销申请流程
2. 把流程的资源文件,进行部署
上传到数据库中使用java代码来进行流程部署。
一次部署操作:ACT_RE_DEPLOYMENT 生成一条记录
ACT_RE_PROCDEF 生成流程定义信息
3. deployment和procdef 表一对多关系。
在procdef表中可以有多条记录,每条记录对应一个流程定义信息。
zs 出差申请
ls 请假申请
流程实例的案例:
/**
* act_ge_property
* act_hi_actinst 流程实例执行历史
* act_hi_identitylink 流程参与用户的信息历史
* act_hi_procinst 流程实例历史信息
* act_hi_taskinst 流程任务历史信息
* act_ru_execution 流程正在执行信息
* act_ru_identitylink 流程参与的用户信息
* act_ru_task 流程的任务信息
*/
@Test
public void testProcessInstance(){
//1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取RuntimeService
RuntimeService runtimeService = processEngine.getRuntimeService();
//3. 根据流程定义的id启动流程
ProcessInstance instance = runtimeService.startProcessInstanceByKey("evectionProcess");
System.out.println("=====流程定义id=========>"+instance.getProcessDefinitionId());
System.out.println("======流程实例id=========>"+instance.getId());
System.out.println("========当前活动的id=======>"+instance.getActivityId());
}
测试运行:
4.2 个人任务查询
/**
* 查询个人任务待执行的任务
*/
@Test
public void testFindPersonalTaskList(){
//1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//获取TaskService
TaskService taskService = processEngine.getTaskService();
//3. 根据流程key和任务负责人查询任务列表
List<Task> taskList = taskService.createTaskQuery()
.processDefinitionKey("evectionProcess")
.taskAssignee("小张")
.list();
System.out.println("=======taskList111======>"+taskList);
for (Task task : taskList) {
System.out.println("=========taskList3333===========>"+taskList);
System.out.println("==========流程实例id=======>"+task.getProcessInstanceId());
System.out.println("========任务id===========>"+task.getId());
System.out.println("=========任务负责人========>"+task.getAssignee());
System.out.println("==========任务名称=========>"+task.getName());
}
System.out.println("=======taskList2222=========>"+taskList);
}
个人流程分析:
SELECT DISTINCT
RES.*
FROM
ACT_RU_TASK RES -- 当前正在运行的任务
INNER JOIN ACT_RE_PROCDEF D ON RES.PROC_DEF_ID_ = D.ID_ -- ACT_RE_PROCDEF 流程实例表
WHERE
RES.ASSIGNEE_ = '小张'
AND D.KEY_ = 'evectionProcess'
ORDER BY
RES.ID_ ASC
LIMIT 2147483647 OFFSET 0
4.3 完成个人任务
/**
* 完成个人出差任务申请
*/
@Test
public void testCompleteTask(){
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取TaskService
TaskService taskService = processEngine.getTaskService();
//3. 根据任务id完成任务
taskService.complete("2505");
}
个人任务完成分析:
INSERT INTO ACT_HI_TASKINST (
ID_,
PROC_DEF_ID_,
PROC_INST_ID_,
EXECUTION_ID_,
NAME_,
PARENT_TASK_ID_,
DESCRIPTION_,
OWNER_,
ASSIGNEE_,
START_TIME_,
CLAIM_TIME_,
END_TIME_,
DURATION_,
DELETE_REASON_,
TASK_DEF_KEY_,
FORM_KEY_,
PRIORITY_,
DUE_DATE_,
CATEGORY_,
TENANT_ID_
)
VALUES
(
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
Parameters: 12502(String), evectionProcess:1:2504(String), 5001(String), 5002(String), 项目组长审批出差单(String), null, null, null, 小张(String), 2022-10-05 09:47:24.717(Timestamp), null, null, null, null, _4(String), null, 50(Integer), null, null, (String)
INSERT INTO ACT_HI_ACTINST (
ID_,
PROC_DEF_ID_,
PROC_INST_ID_,
EXECUTION_ID_,
ACT_ID_,
TASK_ID_,
CALL_PROC_INST_ID_,
ACT_NAME_,
ACT_TYPE_,
ASSIGNEE_,
START_TIME_,
END_TIME_,
DURATION_,
DELETE_REASON_,
TENANT_ID_
)
VALUES
(
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
12501(String), evectionProcess:1:2504(String), 5001(String), 5002(String), _4(String), 12502(String), null, 项目组长审批出差单(String), userTask(String), 小张(String), 2022-10-05 09:47:24.641(Timestamp), null, null, null, (String)
INSERT INTO ACT_HI_IDENTITYLINK (
ID_,
TYPE_,
USER_ID_,
GROUP_ID_,
TASK_ID_,
PROC_INST_ID_
)
VALUES
(?, ?, ?, ?, ?, ?)
12503(String), participant(String), 小张(String), null, null, 5001(String)
INSERT INTO ACT_RU_TASK (
ID_,
REV_,
NAME_,
PARENT_TASK_ID_,
DESCRIPTION_,
PRIORITY_,
CREATE_TIME_,
OWNER_,
ASSIGNEE_,
DELEGATION_,
EXECUTION_ID_,
PROC_INST_ID_,
PROC_DEF_ID_,
TASK_DEF_KEY_,
DUE_DATE_,
CATEGORY_,
SUSPENSION_STATE_,
TENANT_ID_,
FORM_KEY_,
CLAIM_TIME_
)
VALUES
(
?, 1,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
12502(String), 项目组长审批出差单(String), null, null, 50(Integer), 2022-10-05 09:47:24.641(Timestamp), null, 小张(String), null, 5002(String), 5001(String), evectionProcess:1:2504(String), _4(String), null, null, 1(Integer), (String), null, null
INSERT INTO ACT_RU_TASK (
ID_,
REV_,
NAME_,
PARENT_TASK_ID_,
DESCRIPTION_,
PRIORITY_,
CREATE_TIME_,
OWNER_,
ASSIGNEE_,
DELEGATION_,
EXECUTION_ID_,
PROC_INST_ID_,
PROC_DEF_ID_,
TASK_DEF_KEY_,
DUE_DATE_,
CATEGORY_,
SUSPENSION_STATE_,
TENANT_ID_,
FORM_KEY_,
CLAIM_TIME_
)
VALUES
(
?, 1,
?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?
)
12502(String), 项目组长审批出差单(String), null, null, 50(Integer), 2022-10-05 09:47:24.641(Timestamp), null, 小张(String), null, 5002(String), 5001(String), evectionProcess:1:2504(String), _4(String), null, null, 1(Integer), (String), null, null
UPDATE ACT_RU_EXECUTION
SET REV_ = ?, BUSINESS_KEY_ = ?, PROC_DEF_ID_ = ?, ACT_ID_ = ?, IS_ACTIVE_ = ?, IS_CONCURRENT_ = ?, IS_SCOPE_ = ?, IS_EVENT_SCOPE_ = ?, IS_MI_ROOT_ = ?, PARENT_ID_ = ?, SUPER_EXEC_ = ?, ROOT_PROC_INST_ID_ = ?, SUSPENSION_STATE_ = ?, NAME_ = ?, IS_COUNT_ENABLED_ = ?, EVT_SUBSCR_COUNT_ = ?, TASK_COUNT_ = ?, JOB_COUNT_ = ?, TIMER_JOB_COUNT_ = ?, SUSP_JOB_COUNT_ = ?, DEADLETTER_JOB_COUNT_ = ?, VAR_COUNT_ = ?, ID_LINK_COUNT_ = ?
WHERE
ID_ = ?
AND REV_ = ?
Parameters: 2(Integer), null, evectionProcess:1:2504(String), _4(String), true(Boolean), false(Boolean), false(Boolean), false(Boolean), false(Boolean), 5001(String), null, 5001(String), 1(Integer), null, false(Boolean), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 0(Integer), 5002(String), 1(Integer)
UPDATE ACT_HI_ACTINST
SET EXECUTION_ID_ = ?, ASSIGNEE_ = ?, END_TIME_ = ?, DURATION_ = ?, DELETE_REASON_ = ?
WHERE
ID_ = ?
-DELETE
FROM
ACT_RU_TASK
WHERE
ID_ = ?
AND REV_ = ?
Parameters: 2505(String), 1(Integer)
Parameters: 5002(String), xiaomeng(String), 2022-10-05 09:47:24.564(Timestamp), 119954389(Long), null, 5004(String)
4.4 完成出差申请流程
/**
* 完成出差申请流程任务 --项目组长审批
*/
@Test
public void testEvectionApply(){
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取TaskService
TaskService taskService = processEngine.getTaskService();
//获取 小张 - evectionProcess对应的任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("evectionProcess")
.taskAssignee("小张")
.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());
}
程序运行:
/**
* 完成出差申请流程任务 --项目经理审批
*/
@Test
public void testEvectionApply1(){
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取TaskService
TaskService taskService = processEngine.getTaskService();
//获取 王经理 - evectionProcess对应的任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("evectionProcess")
.taskAssignee("王经理")
.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());
}
/**
* 完成出差申请流程任务 --财务审批
*/
@Test
public void testEvectionApply3(){
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取TaskService
TaskService taskService = processEngine.getTaskService();
//获取 王经理 - evectionProcess对应的任务
Task task = taskService.createTaskQuery()
.processDefinitionKey("evectionProcess")
.taskAssignee("李小姐")
.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());
}
程序运行:
4.5 使用zip包部署流程
/**
* 使用zip包进行流程批量部署
*/
@Test
public void testProcessDeployZip(){
//1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//流程部署
//读取资源包文件 构造inputstream
InputStream inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream("bpmn/evection.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());
}
程序运行:
5 流程操作
5.1 流程定义信息查询
/**
* 查询流程定义
*/
@Test
public void queryProcessDefinition(){
//1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3. 获取ProcessDefinitionQuery
ProcessDefinitionQuery definitionQuery = repositoryService.createProcessDefinitionQuery();
//查询当前所有流程定义, 返回流程定义的集合信息
List<ProcessDefinition> definitionList = definitionQuery.processDefinitionKey("evectionProcess")
.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());
}
}
程序运行:
5.2 删除流程
/**
* 删除流程部署
*/
@Test
public void deleteProcessDeployment(){
//1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3. 通过部署id删除部署流程信息
String deploymentId = "1";
repositoryService.deleteDeployment(deploymentId);
}
删除流程部署分析:
# 删除流程部署分析
DELETE
FROM
ACT_GE_BYTEARRAY
WHERE
DEPLOYMENT_ID_ = ?
DELETE
FROM
ACT_RE_DEPLOYMENT
WHERE
ID_ = ?
DELETE
FROM
ACT_RE_PROCDEF
WHERE
DEPLOYMENT_ID_ = ?
Parameters: 1(String)
DELETE
FROM
ACT_RU_EVENT_SUBSCR
WHERE
PROC_DEF_ID_ = ?
AND EXECUTION_ID_ IS NULL
AND PROC_INST_ID_ IS NULL
Parameters : evectionProcess : 1 : 4 (String)
DELETE
FROM
ACT_RU_IDENTITYLINK
WHERE
PROC_DEF_ID_ = ?
Parameters: evectionProcess:1:4(String)
删除流程时需要注意的问题:
/**
* 删除流程部署
* 当前流程中如果没有完成,想要删除的话就必须要进行级联删除
*/
@Test
public void deleteProcessDeployment(){
//1. 创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2. 获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3. 通过部署id删除部署流程信息
String deploymentId = "7501";
//repositoryService.deleteDeployment(deploymentId);
repositoryService.deleteDeployment(deploymentId, true);
}
5.3 流程资源下载
/**
* 下载 流程资源文件
* 方案1:使用Activiti提供的api,来下载资源文件
* 方案2:自己写代码从数据库中下载文件,使用jdbc对bLob类型,clob类型数据读取出来,保存到文件目录
* 解决IO操作:commons-io jar包
*/
@Test
public void downloadProcessDeployment() throws Exception {
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取RepositoryService
RepositoryService repositoryService = processEngine.getRepositoryService();
//3.获取查询对象,根据查询流程定义信息
ProcessDefinition processDefinition = repositoryService.createProcessDefinitionQuery()
.processDefinitionKey("evectionProcess")
.singleResult();
//4.通过留下定义信息获取部署id
String deploymentId = processDefinition.getDeploymentId();
//5.通过RepositoryService传递部署id参数,获取资源(png和bpmn文件)
//5.1获取png图片流
//从数据库流程定义表中动态获取png目录和文件
String pngName = processDefinition.getDiagramResourceName();
InputStream pngInput = repositoryService.getResourceAsStream(deploymentId, pngName);
//5.2 获取bpmn文件流
String bpmnName = processDefinition.getResourceName();
InputStream bpmnInput = repositoryService.getResourceAsStream(deploymentId, bpmnName);
//6.构造输出流
File pngFile = new File("E:\\evection\\evectionFlow01.png");
File bpmnFile = new File("E:\\evection\\evectionFlow01.bpmn");
FileOutputStream pngOutputStream = new FileOutputStream(pngFile);
FileOutputStream bpmnOutputStream = new FileOutputStream(bpmnFile);
//7.输入流和输出流转换
IOUtils.copy(pngInput, pngOutputStream);
IOUtils.copy(bpmnInput, bpmnOutputStream);
//8.关闭流
pngOutputStream.close();
bpmnOutputStream.close();
pngInput.close();
bpmnInput.close();
}
程序运行:
5.4 流程历史信息查询
/**
* 查询流程历史信息
*/
@Test
public void findHistoryInfo(){
//1.创建ProcessEngine
ProcessEngine processEngine = ProcessEngines.getDefaultProcessEngine();
//2.获取HistoryService
HistoryService historyService = processEngine.getHistoryService();
//从数据库查询表
//获取actinst查询对象
HistoricActivityInstanceQuery instanceQuery = historyService.createHistoricActivityInstanceQuery();
//查询actinst表,根据processInstanceId条件查询
//instanceQuery.processInstanceId("15001");
//查询actinst表,根据processDefinitionId条件查询
instanceQuery.processDefinitionId("evectionProcess:1:12504");
//增加排序
instanceQuery.orderByHistoricActivityInstanceStartTime().asc();
//查询所有
List<HistoricActivityInstance> activityInstanceList = instanceQuery.list();
for (HistoricActivityInstance history : activityInstanceList) {
System.out.println("当前活动id:"+history.getActivityId());
System.out.println("当前活动名称:"+history.getActivityName());
System.out.println("当前流程定义id:"+history.getProcessDefinitionId());
System.out.println("当前流程实例id:"+history.getProcessInstanceId());
System.out.println("<======================>");
}
}
程序运行:
如果你在看,就点个“在看”,以上过程我自己的学习过程中的笔记,相信你看到这里也对activiti工作流有一定的认识啦。我们的目标是和人民日报站在一起!坚持一件事不容易,点个“赞”,点个“在看”,你会变好看!