Activiti是什么,为什么要用它?
Activiti项目是一项新的基于Apache许可的开源BPM平台,其实就是一个工作审批流,在我们日常生活中,审批是非常常见的,加班打车,需要把发票贴到报销单,然后提交给组长,组长审批完毕,提交给部门主管,部门主管审核完毕,给财务部门,财务部分审核完毕,给你银行卡打钱,一个审批的流程结束了。
引入pom
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-engine</artifactId>
<version>5.22.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.activiti/activiti-spring -->
<dependency>
<groupId>org.activiti</groupId>
<artifactId>activiti-spring</artifactId>
<version>5.22.0</version>
</dependency>
初始化生成表
public static void main(String[] args) {
//配置数据源 方式一
ProcessEngineConfiguration configuration =
ProcessEngineConfiguration.createStandaloneProcessEngineConfiguration();
configuration.setJdbcDriver("com.mysql.jdbc.Driver");
configuration.setJdbcUrl("jdbc:mysql://127.0.0.1:3306/activiti?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=false");
configuration.setJdbcUsername("root");
configuration.setJdbcPassword("zsq2170");
//配置数据源 方式二
// DriverManagerDataSource dataSource=new DriverManagerDataSource();
// dataSource.setDriverClassName("com.mysql.jdbc.Driver");
// dataSource.setUrl("jdbc:mysql://127.0.0.1:3306/activiti930?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&autoReconnect=true&rewriteBatchedStatements=true&zeroDateTimeBehavior=convertToNull&serverTimezone=Asia/Shanghai&useSSL=false");
// dataSource.setUsername("root");
// dataSource.setPassword("zsq2170");
// configuration.setDataSource(dataSource);
//配置表初始化方式
//ProcessEngineConfiguration.DB_SCHEMA_UPDATE_FALSE 如果数据库里面没有activiti的表,也不会创建
//ProcessEngineConfiguration.DB_SCHEMA_UPDATE_CREATE_DROP 创建表,使用完之后删除
//ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE 如果数据库里面没有表,就创建
//configuration.setDatabaseSchemaUpdate(ProcessEngineConfiguration.DB_SCHEMA_UPDATE_TRUE);
configuration.setDatabaseSchemaUpdate("drop-create");
//得到流程引擎
ProcessEngine processEngine = configuration.buildProcessEngine();
System.out.println("初始化完成");
}
描述表信息(初始化后自动生成表)
表结构描述:
#RepositoryService
SELECT * FROM ACT_GE_BYTEARRAY; #二进制文件表
SELECT * FROM ACT_RE_DEPLOYMENT; #流程部署表
SELECT * FROM ACT_RE_PROCDEF; #流程定义
SELECT * FROM ACT_GE_PROPERTY; #工作流的ID算法和版本信息表
#RuntimeService TaskService
SELECT * FROM ACT_RU_TASK; #流程启动一次只要没执行完,就会有一条数据
SELECT * FROM ACT_RU_EXECUTION; #可能有多条数据
SELECT * FROM ACT_RU_VARIABLE; #记录流程运行时的流程变量
SELECT * FROM ACT_RU_IDENTITYLINK; #存放流程办理人的信息
#HistoryService
SELECT * FROM ACT_HI_PROCINST; #历史流程实例
SELECT * FROM ACT_HI_TASKINST; #历史任务实例
SELECT * FROM ACT_HI_ACTINST; #历史活动节点表
SELECT * FROM ACT_HI_VARINST; #历史流程变量表
SELECT * FROM ACT_HI_IDENTITYLINK; #历史办理人表activiti
SELECT * FROM ACT_HI_COMMENT; #批注表
SELECT * FROM ACT_HI_ATTACHMENT; #附件表
#相关id总结
部署ID ACT_RE_DEPLOYMENT 的 id
流程定义ID ACT_RE_PROCDEF 的 id
流程实例ID ACT_RU_EXECUTION 的 id
执行实例ID ACT_RU_TASK 的 EXECUTION_ID_
任务ID ACT_RU_TASK 的 id
画流程图
eclipse安装插件教程 https://blog.youkuaiyun.com/qq_23888451/article/details/83180874
几个人员节点依次修改名称,并设置办理人
流程部署
图画好后压缩成zip压缩包待用
/**
* 2.流程部署 ->获取流程部署对象
*/
@Test
public void getDeployment(){
ProcessEngine processEngine = getProcessEngine();
//方式一 根据zip压缩包部署 一定得是zip
InputStream inputStream = this.getClass().getResourceAsStream("/helloworld.zip");
RepositoryService repositoryService = processEngine.getRepositoryService();
//流程部署 ,获取流程部署对象
Deployment deploy = repositoryService.createDeployment().name("请假流程001")
.addZipInputStream(new ZipInputStream(inputStream))
.deploy();
//方式二 更加bpmn文件部署
// RepositoryService repositoryService = processEngine.getRepositoryService();
// //流程部署 ,获取流程部署对象
// Deployment deploy = repositoryService.createDeployment().name("请假流程001")
// .addClasspathResource("templates/helloworld.bpmn")
// .deploy();
System.out.println("流程部署成功 流程id"+deploy.getId());
}
启动流程操作
/**
* 3.启动流程
*/
@Test
public void startProcess(){
ProcessEngine processEngine = getProcessEngine();
RuntimeService runtimeService = processEngine.getRuntimeService();
//方式一 根据流程定义id
// String processDefinitionId="helloword:1:4";
// runtimeService.startProcessInstanceById(processDefinitionId);
/**
* 方式二 processDefinitionId -> 流程定义id
* variables -> map流程变量
*/
//runtimeService.startProcessInstanceById(processDefinitionId,variables);
/**
* 方式三 processDefinitionId -> 流程定义id
* businessKey -> string 业务id 把业务id和流程执行实例进行绑定
*/
//runtimeService.startProcessInstanceById(processDefinitionId,businessKey);
/**
* 方式四 processDefinitionId -> 流程定义id
* businessKey -> string 业务id 把业务id和流程执行实例进行绑定
* variables -> map流程变量
*/
//runtimeService.startProcessInstanceById(processDefinitionId,businessKey,variables);
//方式五
/**
* 根据流程定义的key启动
*/
String processDefinitionKey="helloworld";
// ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey);
//创建流程变量对象
Map<String,Object> variables=new HashMap<>();
variables.put("请假天数",5);
variables.put("请假原因","约会");
variables.put("请假时间",new Date());
ProcessInstance processInstance = runtimeService.startProcessInstanceByKey(processDefinitionKey, variables);
// runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey);
// runtimeService.startProcessInstanceByKey(processDefinitionId,businessKey,variables);
//============实际开发中使用==========
//runtimeService.startProcessInstanceByKey(processDefinitionKey,businessKey);
// //runtimeService.startProcessInstanceByKey(processDefinitionId,businessKey,variables);
System.out.println("流程启动成功"+processInstance.getId()+" "+processInstance.getProcessDefinitionId());
}
查询任务
/**
* 4.查询任务
*/
@Test
public void findTask(){
ProcessEngine processEngine = getProcessEngine();
TaskService taskService = processEngine.getTaskService();
String assignee="张三";
List<Task> list = taskService.createTaskQuery()
.taskAssignee(assignee) //根据办理人查询
// .taskAssigneeLike() //根据办理人模糊查询
// .deploymentId() //根据部署id查询
// .deploymentIdIn() //根据部署id集合查询
// .executionId() //根据执行实例id查询
// .processDefinitionId() //根据流程定义id
// .processDefinitionKey()//根据流程定义key
// .processDefinitionKeyIn()
// .processDefinitionKeyLike()
// .processDefinitionName() //根据流程定义名称
// .processDefinitionNameLike()
// .processInstanceBusinessKey() //根据业务id
// .processInstanceBusinessKeyLike()
.list();
if(!CollectionUtils.isEmpty(list)){
for (Task task :list){
System.err.println("任务=="+task.toString());
System.err.println("任务Id=="+task.getId());//2502
System.err.println("流程实例id=="+task.getProcessInstanceId());
System.err.println("执行实例id=="+task.getExecutionId());
System.err.println("流程定义id=="+task.getProcessDefinitionId());
System.err.println("任务名称=="+task.getName());
System.err.println("任务办理人=="+task.getAssignee());
System.err.println("##########");
}
}
System.err.println("========任务查询完成===========");
}
办理任务
/**
* 5.办理任务
*/
@Test
public void complateTask(){
ProcessEngine processEngine = getProcessEngine();
TaskService taskService = processEngine.getTaskService();
String taskId="2504";
//方法1 根据任务id去完成
taskService.complete(taskId);
//方法2 根据任务id去完成,并指定流程变量
// taskService.complete(taskId,variables);
// taskService.complete(taskId,variables,localScope);
System.out.println("任务完成");
}
删除流程定义
/**
* 5.删除流程定义
*/
@Test
public void deleteProcDef(){
ProcessEngine processEngine = getProcessEngine();
RepositoryService repositoryService = processEngine.getRepositoryService();
String deploymentId="20001";
//根据流程部署id删除,如果当前id的流程正在执行,那么会报错
// repositoryService.deleteDeployment(deploymentId);
//根据流程部署id删除,删除流程定义,如果当前id流程正在执行,那么会把正在执行的流程数据删除 act_ru_*和act_hi_*表里的数据
repositoryService.deleteDeployment(deploymentId,true);
System.out.println("删除成功");
}
判断流程是否结束
/**
* 6.判断流程是否结束 .更新业务表里面的状态
*/
@Test
public void isComplete(){
ProcessEngine processEngine = getProcessEngine();
//已知流程实例id
RuntimeService runtimeService = processEngine.getRuntimeService();
String processInstanceId="2501";
// String taskId="5002";
// TaskService taskService = processEngine.getTaskService();
// Task task = taskService.createTaskQuery().taskId(taskId).singleResult();
// String processInstanceId = task.getProcessInstanceId();
// System.out.println("processInstanceId===="+processInstanceId);
ProcessInstance processInstance =
runtimeService.createProcessInstanceQuery().processInstanceId(processInstanceId).singleResult();
if(null!=processInstance){
System.out.println("流程未结束");
}else {
System.out.println("流程结束");
}
}