工作流 jbpm(图文并茂)

news2024/11/17 17:28:54

文章目录

    • 1 工作流概述
    • 2 jBPM概述
    • 3 jBPM开发环境搭建及其配置
      • 3.1 准备工作
      • 3.2 搭建jBPM开发环境
      • 3.3 加入jar包
    • 4 系统数据库表介绍
      • 4.1 建表
      • 4.2 数据库逻辑关系
        • 4.2.1 资源库与运行时的表
        • 4.2.2 历史数据表
      • 4.3 表结构
      • 4.4 流程操作与数表交互说明
    • 5 相关概念
    • 6 流程图说明
      • 6.0 快速上手
      • 6.1 活动Activity / 节点Node
        • 6.1.1 start 开始活动
        • 6.1.2 end 结束活动
        • 6.1.3 task 任务活动
        • 6.1.4 decision 判断活动
        • 6.1.5 fork/join 分支/聚合活动
      • 6.2 流转 Transition / 连线 (单向箭头)
        • 6.2.1 开始活动
        • 6.2.2 结束活动
        • 6.2.3 其他活动
    • 7 画图与配置
      • 7.1 画图
      • 7.2 配置
        • 7.2.1 配置任务办理人
          • 7.2.1.1 写死的方式配置任务办理人(不推荐)
          • 7.2.1.2 #{}方式配置任务办理人
          • 7.2.1.3 实现接口方式配置任务办理人
          • 7.2.1.4 方法指定方式分配任务办理人
        • 7.2.2 配置节点属性
          • 7.2.2.1 判断节点(decision)
          • 7.2.2.2 分支/聚合节点
      • 7.3 完成画图与配置后的效果
        • 7.3.1 完成后的图
        • 7.3.2 完成后配置的xml文件
    • 8 操作API
      • 8.1 部署流程
        • 8.1.1 部署方式1-源文件
        • 8.1.2 部署方式2-zip包
      • 8.2 查询流程实例
        • 8.2.1 查询所有
        • 8.2.2 查询所有最新版本的流程定义
      • 8.3 删除流程定义
        • 8.3.1 按照id删除(有关联信息会抛异常)
        • 8.3.2 按照id删除(会删除关联信息)
        • 8.3.3 按照key删除
      • 8.4 获取部署时的文件资源
        • 8.4.1 获取部署时的文件资源方式1
        • 8.4.2 获取部署时的文件资源方式2
      • 8.5 启动实例
        • 8.5.1 按照key启动(不加参数)
        • 8.5.2 按照key启动(加入参数)
        • 8.5.3 启动流程实例的说明
      • 8.6 查询任务
        • 8.6.1 查询所有未办理任务
        • 8.6.2 查询个人未办理任务
        • 8.6.3 查询个人的待办组任务
      • 8.7 办理任务
        • 8.7.1 办理个人任务
        • 8.7.2 办理个人组任务
      • 8.8 驳回任务
      • 8.9 流程变量
        • 8.9.2 设置流程变量
        • 8.9.3 获取流程变量
      • 8.10 组任务
        • 8.10.1 组任务的分配
          • 8.10.1.1 写死的方式指定
          • 8.10.1.2 实现AssignmentHandler接口指定
        • 8.10.2 查询自己的组任务
        • 8.10.3 办理自己的组任务
      • 8.10 组任务
        • 8.10.1 组任务的分配
          • 8.10.1.1 写死的方式指定
          • 8.10.1.2 实现AssignmentHandler接口指定
        • 8.10.2 查询自己的组任务
        • 8.10.3 办理自己的组任务

1 工作流概述

工作流(Workflow),就是“业务过程的部分或整体在计算机应用环境下的自动化”,它主要解决的是“使在多个参与者之间按照某种预定义的规则传递文档、信息或任务的过程自动进行,从而实现某个预期的业务目标,或者促使此目标的实现” 简单的说,就是将工作的流程通过程序管理起来,以表单审核和任务办理为主体,实现办公自动化

工作流框架,将业务流程管理起来, 所有业务流程操作,围绕工作流框架进行, 基于表单提交和任务办理, 实现工作业务流程 自动流转。 工作流框架有:jBPM、Activiti、OSWorkflow、ActiveBPEL、YAWL等

2 jBPM概述

jBPM: Java Business Process Management(业务流程管理)

jBPM,全称是Java Business Process Management(业务流程管理) 是一款开源的工作流产品,功能强大、小巧灵活 jBPM在2004年10月18日,发布了2.0版本,并在同一天加入了JBoss,成为了JBoss企业中间件平台的一个组成部分,它的名称也改成JBoss jBPM jBPM采用XML结构的流程描述语言JPDL来描述工作流程 jBPM使用Hibernate作为持久层工具,可以在各大主流数据库中使用

jBPM是一种基于Java语言的开源工作流/业务流程管理框架(Framework),它主要包括工作流引擎(WorkflowEngine)和基于Eclipse平台的图形化流程设计器(GraphProcessDesigner)。jBPM凭借其良好的开放性和扩展性被广泛应用于所有需要“流程”的企业应用系统中,这包括金融、电信、制造业、政府等诸多行业领域。

官网:http://www.jboss.org/jbpm/

版本:该文档采用JBPM4.4


3 jBPM开发环境搭建及其配置

3.1 准备工作

下载jBPM4.4开发包

下载地址: https://sourceforge.net/projects/jbpm/files/jBPM4/jbpm-4.4/

jBPM4.4开发包解压后的目录结构如下图:
在这里插入图片描述

3.2 搭建jBPM开发环境

如下操作

在这里插入图片描述

继续:

在这里插入图片描述

点OK,如下图—全选:

在这里插入图片描述

然后next–>next–>accept–>finsh。然后会进入安装,安装完成后重启。

然后在window–>Show View–>other可以找到如下图所示,证明安装成功。

在这里插入图片描述

3.3 加入jar包

jbpm解压文件 下的lib文件下的包

在这里插入图片描述

4 系统数据库表介绍

4.1 建表

该系统自带18张表,用于支撑该系统的逻辑与流程业务;

建表语句如下:

create database jbpmdb;
use jbpmdb;


DROP TABLE IF EXISTS `jbpm4_deployment`;
CREATE TABLE IF NOT EXISTS `jbpm4_deployment` (
 `DBID_` bigint(20) NOT NULL,
 `NAME_` longtext,
 `TIMESTAMP_` bigint(20) DEFAULT NULL,
 `STATE_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



DROP TABLE IF EXISTS `jbpm4_deployprop`;
CREATE TABLE IF NOT EXISTS `jbpm4_deployprop` (
 `DBID_` bigint(20) NOT NULL,
 `DEPLOYMENT_` bigint(20) DEFAULT NULL,
 `OBJNAME_` varchar(255) DEFAULT NULL,
 `KEY_` varchar(255) DEFAULT NULL,
 `STRINGVAL_` varchar(255) DEFAULT NULL,
 `LONGVAL_` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_DEPLPROP_DEPL` (`DEPLOYMENT_`),
 KEY `FK_DEPLPROP_DEPL` (`DEPLOYMENT_`),
 CONSTRAINT `FK_DEPLPROP_DEPL` FOREIGN KEY (`DEPLOYMENT_`) REFERENCES `jbpm4_deployment` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

DROP TABLE IF EXISTS `jbpm4_execution`;
CREATE TABLE IF NOT EXISTS `jbpm4_execution` (
 `DBID_` bigint(20) NOT NULL,
 `CLASS_` varchar(255) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `ACTIVITYNAME_` varchar(255) DEFAULT NULL,
 `PROCDEFID_` varchar(255) DEFAULT NULL,
 `HASVARS_` bit(1) DEFAULT NULL,
 `NAME_` varchar(255) DEFAULT NULL,
 `KEY_` varchar(255) DEFAULT NULL,
 `ID_` varchar(255) DEFAULT NULL,
 `STATE_` varchar(255) DEFAULT NULL,
 `SUSPHISTSTATE_` varchar(255) DEFAULT NULL,
 `PRIORITY_` int(11) DEFAULT NULL,
 `HISACTINST_` bigint(20) DEFAULT NULL,
 `PARENT_` bigint(20) DEFAULT NULL,
 `INSTANCE_` bigint(20) DEFAULT NULL,
 `SUPEREXEC_` bigint(20) DEFAULT NULL,
 `SUBPROCINST_` bigint(20) DEFAULT NULL,
 `PARENT_IDX_` int(11) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 UNIQUE KEY `ID_` (`ID_`),
 KEY `IDX_EXEC_SUPEREXEC` (`SUPEREXEC_`),
 KEY `IDX_EXEC_INSTANCE` (`INSTANCE_`),
 KEY `IDX_EXEC_SUBPI` (`SUBPROCINST_`),
 KEY `IDX_EXEC_PARENT` (`PARENT_`),
 KEY `FK_EXEC_PARENT` (`PARENT_`),
 KEY `FK_EXEC_SUBPI` (`SUBPROCINST_`),
 KEY `FK_EXEC_INSTANCE` (`INSTANCE_`),
 KEY `FK_EXEC_SUPEREXEC` (`SUPEREXEC_`),
 CONSTRAINT `FK_EXEC_INSTANCE` FOREIGN KEY (`INSTANCE_`) REFERENCES `jbpm4_execution` (`DBID_`),
 CONSTRAINT `FK_EXEC_PARENT` FOREIGN KEY (`PARENT_`) REFERENCES `jbpm4_execution` (`DBID_`),
 CONSTRAINT `FK_EXEC_SUBPI` FOREIGN KEY (`SUBPROCINST_`) REFERENCES `jbpm4_execution` (`DBID_`),
 CONSTRAINT `FK_EXEC_SUPEREXEC` FOREIGN KEY (`SUPEREXEC_`) REFERENCES `jbpm4_execution` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_hist_actinst`;
CREATE TABLE IF NOT EXISTS `jbpm4_hist_actinst` (
 `DBID_` bigint(20) NOT NULL,
 `CLASS_` varchar(255) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `HPROCI_` bigint(20) DEFAULT NULL,
 `engine_` varchar(255) DEFAULT NULL,
 `EXECUTION_` varchar(255) DEFAULT NULL,
 `ACTIVITY_NAME_` varchar(255) DEFAULT NULL,
 `START_` datetime DEFAULT NULL,
 `END_` datetime DEFAULT NULL,
 `DURATION_` bigint(20) DEFAULT NULL,
 `TRANSITION_` varchar(255) DEFAULT NULL,
 `NEXTIDX_` int(11) DEFAULT NULL,
 `HTASK_` bigint(20) DEFAULT NULL,
 `TYPE_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_HACTI_HPROCI` (`HPROCI_`),
 KEY `IDX_HTI_HTASK` (`HTASK_`),
 KEY `FK_HACTI_HPROCI` (`HPROCI_`),
 KEY `FK_HTI_HTASK` (`HTASK_`),
 CONSTRAINT `FK_HACTI_HPROCI` FOREIGN KEY (`HPROCI_`) REFERENCES `jbpm4_hist_procinst` (`DBID_`),
 CONSTRAINT `FK_HTI_HTASK` FOREIGN KEY (`HTASK_`) REFERENCES `jbpm4_hist_task` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_hist_detail`;
CREATE TABLE IF NOT EXISTS `jbpm4_hist_detail` (
 `DBID_` bigint(20) NOT NULL,
 `CLASS_` varchar(255) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `USERID_` varchar(255) DEFAULT NULL,
 `TIME_` datetime DEFAULT NULL,
 `HPROCI_` bigint(20) DEFAULT NULL,
 `HPROCIIDX_` int(11) DEFAULT NULL,
 `HACTI_` bigint(20) DEFAULT NULL,
 `HACTIIDX_` int(11) DEFAULT NULL,
 `HTASK_` bigint(20) DEFAULT NULL,
 `HTASKIDX_` int(11) DEFAULT NULL,
 `HVAR_` bigint(20) DEFAULT NULL,
 `HVARIDX_` int(11) DEFAULT NULL,
 `MESSAGE_` longtext,
 `OLD_STR_` varchar(255) DEFAULT NULL,
 `NEW_STR_` varchar(255) DEFAULT NULL,
 `OLD_INT_` int(11) DEFAULT NULL,
 `NEW_INT_` int(11) DEFAULT NULL,
 `OLD_TIME_` datetime DEFAULT NULL,
 `NEW_TIME_` datetime DEFAULT NULL,
 `PARENT_` bigint(20) DEFAULT NULL,
 `PARENT_IDX_` int(11) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_HDET_HACTI` (`HACTI_`),
 KEY `IDX_HDET_HPROCI` (`HPROCI_`),
 KEY `IDX_HDET_HVAR` (`HVAR_`),
 KEY `IDX_HDET_HTASK` (`HTASK_`),
 KEY `FK_HDETAIL_HPROCI` (`HPROCI_`),
 KEY `FK_HDETAIL_HACTI` (`HACTI_`),
 KEY `FK_HDETAIL_HTASK` (`HTASK_`),
 KEY `FK_HDETAIL_HVAR` (`HVAR_`),
 CONSTRAINT `FK_HDETAIL_HACTI` FOREIGN KEY (`HACTI_`) REFERENCES `jbpm4_hist_actinst` (`DBID_`),
 CONSTRAINT `FK_HDETAIL_HPROCI` FOREIGN KEY (`HPROCI_`) REFERENCES `jbpm4_hist_procinst` (`DBID_`),
 CONSTRAINT `FK_HDETAIL_HTASK` FOREIGN KEY (`HTASK_`) REFERENCES `jbpm4_hist_task` (`DBID_`),
 CONSTRAINT `FK_HDETAIL_HVAR` FOREIGN KEY (`HVAR_`) REFERENCES `jbpm4_hist_var` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_hist_procinst`;
CREATE TABLE IF NOT EXISTS `jbpm4_hist_procinst` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `ID_` varchar(255) DEFAULT NULL,
 `PROCDEFID_` varchar(255) DEFAULT NULL,
 `KEY_` varchar(255) DEFAULT NULL,
 `START_` datetime DEFAULT NULL,
 `END_` datetime DEFAULT NULL,
 `DURATION_` bigint(20) DEFAULT NULL,
 `STATE_` varchar(255) DEFAULT NULL,
 `ENDACTIVITY_` varchar(255) DEFAULT NULL,
 `NEXTIDX_` int(11) DEFAULT NULL,
 PRIMARY KEY (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



DROP TABLE IF EXISTS `jbpm4_hist_task`;
CREATE TABLE IF NOT EXISTS `jbpm4_hist_task` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `EXECUTION_` varchar(255) DEFAULT NULL,
 `OUTCOME_` varchar(255) DEFAULT NULL,
 `ASSIGNEE_` varchar(255) DEFAULT NULL,
 `PRIORITY_` int(11) DEFAULT NULL,
 `STATE_` varchar(255) DEFAULT NULL,
 `CREATE_` datetime DEFAULT NULL,
 `END_` datetime DEFAULT NULL,
 `DURATION_` bigint(20) DEFAULT NULL,
 `NEXTIDX_` int(11) DEFAULT NULL,
 `SUPERTASK_` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_HSUPERT_SUB` (`SUPERTASK_`),
 KEY `FK_HSUPERT_SUB` (`SUPERTASK_`),
 CONSTRAINT `FK_HSUPERT_SUB` FOREIGN KEY (`SUPERTASK_`) REFERENCES `jbpm4_hist_task` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

DROP TABLE IF EXISTS `jbpm4_hist_var`;
CREATE TABLE IF NOT EXISTS `jbpm4_hist_var` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `PROCINSTID_` varchar(255) DEFAULT NULL,
 `EXECUTIONID_` varchar(255) DEFAULT NULL,
 `VARNAME_` varchar(255) DEFAULT NULL,
 `VALUE_` varchar(255) DEFAULT NULL,
 `HPROCI_` bigint(20) DEFAULT NULL,
 `HTASK_` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_HVAR_HPROCI` (`HPROCI_`),
 KEY `IDX_HVAR_HTASK` (`HTASK_`),
 KEY `FK_HVAR_HPROCI` (`HPROCI_`),
 KEY `FK_HVAR_HTASK` (`HTASK_`),
 CONSTRAINT `FK_HVAR_HPROCI` FOREIGN KEY (`HPROCI_`) REFERENCES `jbpm4_hist_procinst` (`DBID_`),
 CONSTRAINT `FK_HVAR_HTASK` FOREIGN KEY (`HTASK_`) REFERENCES `jbpm4_hist_task` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



DROP TABLE IF EXISTS `jbpm4_id_group`;
CREATE TABLE IF NOT EXISTS `jbpm4_id_group` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `ID_` varchar(255) DEFAULT NULL,
 `NAME_` varchar(255) DEFAULT NULL,
 `engine_` varchar(255) DEFAULT NULL,
 `PARENT_` bigint(20) DEFAULT NULL,
 `TYPE_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_GROUP_PARENT` (`PARENT_`),
 KEY `FK_GROUP_PARENT` (`PARENT_`),
 CONSTRAINT `FK_GROUP_PARENT` FOREIGN KEY (`PARENT_`) REFERENCES `jbpm4_id_group` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_id_membership`;
CREATE TABLE IF NOT EXISTS `jbpm4_id_membership` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `USER_` bigint(20) DEFAULT NULL,
 `GROUP_` bigint(20) DEFAULT NULL,
 `NAME_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_MEM_USER` (`USER_`),
 KEY `IDX_MEM_GROUP` (`GROUP_`),
 KEY `FK_MEM_GROUP` (`GROUP_`),
 KEY `FK_MEM_USER` (`USER_`),
 CONSTRAINT `FK_MEM_GROUP` FOREIGN KEY (`GROUP_`) REFERENCES `jbpm4_id_group` (`DBID_`),
 CONSTRAINT `FK_MEM_USER` FOREIGN KEY (`USER_`) REFERENCES `jbpm4_id_user` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



DROP TABLE IF EXISTS `jbpm4_id_user`;
CREATE TABLE IF NOT EXISTS `jbpm4_id_user` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `ID_` varchar(255) DEFAULT NULL,
 `PASSWORD_` varchar(255) DEFAULT NULL,
 `GIVENNAME_` varchar(255) DEFAULT NULL,
 `FAMILYNAME_` varchar(255) DEFAULT NULL,
 `BUSINESSEMAIL_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_job`;
CREATE TABLE IF NOT EXISTS `jbpm4_job` (
 `DBID_` bigint(20) NOT NULL,
 `CLASS_` varchar(255) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `DUEDATE_` datetime DEFAULT NULL,
 `STATE_` varchar(255) DEFAULT NULL,
 `ISEXCLUSIVE_` bit(1) DEFAULT NULL,
 `LOCKOWNER_` varchar(255) DEFAULT NULL,
 `LOCKEXPTIME_` datetime DEFAULT NULL,
 `EXCEPTION_` longtext,
 `RETRIES_` int(11) DEFAULT NULL,
 `PROCESSINSTANCE_` bigint(20) DEFAULT NULL,
 `EXECUTION_` bigint(20) DEFAULT NULL,
 `CFG_` bigint(20) DEFAULT NULL,
 `SIGNAL_` varchar(255) DEFAULT NULL,
 `EVENT_` varchar(255) DEFAULT NULL,
 `REPEAT_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_JOBRETRIES` (`RETRIES_`),
 KEY `IDX_JOB_CFG` (`CFG_`),
 KEY `IDX_JOB_PRINST` (`PROCESSINSTANCE_`),
 KEY `IDX_JOB_EXE` (`EXECUTION_`),
 KEY `IDX_JOBLOCKEXP` (`LOCKEXPTIME_`),
 KEY `IDX_JOBDUEDATE` (`DUEDATE_`),
 KEY `FK_JOB_CFG` (`CFG_`),
 CONSTRAINT `FK_JOB_CFG` FOREIGN KEY (`CFG_`) REFERENCES `jbpm4_lob` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



DROP TABLE IF EXISTS `jbpm4_lob`;
CREATE TABLE IF NOT EXISTS `jbpm4_lob` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `BLOB_VALUE_` longblob,
 `DEPLOYMENT_` bigint(20) DEFAULT NULL,
 `NAME_` longtext,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_LOB_DEPLOYMENT` (`DEPLOYMENT_`),
 KEY `FK_LOB_DEPLOYMENT` (`DEPLOYMENT_`),
 CONSTRAINT `FK_LOB_DEPLOYMENT` FOREIGN KEY (`DEPLOYMENT_`) REFERENCES `jbpm4_deployment` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



DROP TABLE IF EXISTS `jbpm4_participation`;
CREATE TABLE IF NOT EXISTS `jbpm4_participation` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `GROUPID_` varchar(255) DEFAULT NULL,
 `USERID_` varchar(255) DEFAULT NULL,
 `engine_` varchar(255) DEFAULT NULL,
 `TASK_` bigint(20) DEFAULT NULL,
 `SWIMLANE_` bigint(20) DEFAULT NULL,
 `TYPE_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_PART_TASK` (`TASK_`),
 KEY `FK_PART_SWIMLANE` (`SWIMLANE_`),
 KEY `FK_PART_TASK` (`TASK_`),
 CONSTRAINT `FK_PART_SWIMLANE` FOREIGN KEY (`SWIMLANE_`) REFERENCES `jbpm4_swimlane` (`DBID_`),
 CONSTRAINT `FK_PART_TASK` FOREIGN KEY (`TASK_`) REFERENCES `jbpm4_task` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;



DROP TABLE IF EXISTS `jbpm4_property`;
CREATE TABLE IF NOT EXISTS `jbpm4_property` (
 `KEY_` varchar(255) NOT NULL,
 `VERSION_` int(11) NOT NULL,
 `VALUE_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`KEY_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_swimlane`;
CREATE TABLE IF NOT EXISTS `jbpm4_swimlane` (
 `DBID_` bigint(20) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `NAME_` varchar(255) DEFAULT NULL,
 `ASSIGNEE_` varchar(255) DEFAULT NULL,
 `EXECUTION_` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_SWIMLANE_EXEC` (`EXECUTION_`),
 KEY `FK_SWIMLANE_EXEC` (`EXECUTION_`),
 CONSTRAINT `FK_SWIMLANE_EXEC` FOREIGN KEY (`EXECUTION_`) REFERENCES `jbpm4_execution` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_task`;
CREATE TABLE IF NOT EXISTS `jbpm4_task` (
 `DBID_` bigint(20) NOT NULL,
 `CLASS_` char(1) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `NAME_` varchar(255) DEFAULT NULL,
 `DESCR_` longtext,
 `STATE_` varchar(255) DEFAULT NULL,
 `SUSPHISTSTATE_` varchar(255) DEFAULT NULL,
 `ASSIGNEE_` varchar(255) DEFAULT NULL,
 `FORM_` varchar(255) DEFAULT NULL,
 `PRIORITY_` int(11) DEFAULT NULL,
 `CREATE_` datetime DEFAULT NULL,
 `DUEDATE_` datetime DEFAULT NULL,
 `PROGRESS_` int(11) DEFAULT NULL,
 `SIGNALLING_` bit(1) DEFAULT NULL,
 `EXECUTION_ID_` varchar(255) DEFAULT NULL,
 `ACTIVITY_NAME_` varchar(255) DEFAULT NULL,
 `HASVARS_` bit(1) DEFAULT NULL,
 `SUPERTASK_` bigint(20) DEFAULT NULL,
 `EXECUTION_` bigint(20) DEFAULT NULL,
 `PROCINST_` bigint(20) DEFAULT NULL,
 `SWIMLANE_` bigint(20) DEFAULT NULL,
 `TASKDEFNAME_` varchar(255) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_TASK_SUPERTASK` (`SUPERTASK_`),
 KEY `FK_TASK_SWIML` (`SWIMLANE_`),
 KEY `FK_TASK_SUPERTASK` (`SUPERTASK_`),
 CONSTRAINT `FK_TASK_SUPERTASK` FOREIGN KEY (`SUPERTASK_`) REFERENCES `jbpm4_task` (`DBID_`),
 CONSTRAINT `FK_TASK_SWIML` FOREIGN KEY (`SWIMLANE_`) REFERENCES `jbpm4_swimlane` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;


DROP TABLE IF EXISTS `jbpm4_variable`;
CREATE TABLE IF NOT EXISTS `jbpm4_variable` (
 `DBID_` bigint(20) NOT NULL,
 `CLASS_` varchar(255) NOT NULL,
 `DBVERSION_` int(11) NOT NULL,
 `KEY_` varchar(255) DEFAULT NULL,
 `CONVERTER_` varchar(255) DEFAULT NULL,
 `HIST_` bit(1) DEFAULT NULL,
 `EXECUTION_` bigint(20) DEFAULT NULL,
 `TASK_` bigint(20) DEFAULT NULL,
 `LOB_` bigint(20) DEFAULT NULL,
 `DATE_VALUE_` datetime DEFAULT NULL,
 `DOUBLE_VALUE_` double DEFAULT NULL,
 `CLASSNAME_` varchar(255) DEFAULT NULL,
 `LONG_VALUE_` bigint(20) DEFAULT NULL,
 `STRING_VALUE_` varchar(255) DEFAULT NULL,
 `TEXT_VALUE_` longtext,
 `EXESYS_` bigint(20) DEFAULT NULL,
 PRIMARY KEY (`DBID_`),
 KEY `IDX_VAR_EXESYS` (`EXESYS_`),
 KEY `IDX_VAR_TASK` (`TASK_`),
 KEY `IDX_VAR_EXECUTION` (`EXECUTION_`),
 KEY `IDX_VAR_LOB` (`LOB_`),
 KEY `FK_VAR_LOB` (`LOB_`),
 KEY `FK_VAR_EXECUTION` (`EXECUTION_`),
 KEY `FK_VAR_EXESYS` (`EXESYS_`),
 KEY `FK_VAR_TASK` (`TASK_`),
 CONSTRAINT `FK_VAR_EXECUTION` FOREIGN KEY (`EXECUTION_`) REFERENCES `jbpm4_execution` (`DBID_`),
 CONSTRAINT `FK_VAR_EXESYS` FOREIGN KEY (`EXESYS_`) REFERENCES `jbpm4_execution` (`DBID_`),
 CONSTRAINT `FK_VAR_LOB` FOREIGN KEY (`LOB_`) REFERENCES `jbpm4_lob` (`DBID_`),
 CONSTRAINT `FK_VAR_TASK` FOREIGN KEY (`TASK_`) REFERENCES `jbpm4_task` (`DBID_`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

4.2 数据库逻辑关系

18张表简介:

在这里插入图片描述

4.2.1 资源库与运行时的表

在这里插入图片描述

4.2.2 历史数据表

在这里插入图片描述

4.3 表结构

表JBPM4_DEPLOYMENT

表名流程定义表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK流程模版标识
NAME_CLOBY流程模版名称
TIMESTAMP_NUMBER(19)Y时间戳
STATE_VARCHAR2(255 CHAR)Y可用状态
补充说明一条 jbpm4_deployment 记录需要对应4 条jbpm4_deployprop 记录

表JBPM4_DEPLOYPROP

表名流程定义属性表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK主键
DEPLOYMENT_NUMBER(19)YFK(JBPM4_DEPLOYMENT, DBID_)流程ID
OBJNAME_VARCHAR2(255 CHAR)Y流程名称
KEY_VARCHAR2(255 CHAR)Y类型
STRINGVAL_VARCHAR2(255 CHAR)Y类型是字符串时的值
LONGVAL_NUMBER(19)Y类型是数值时的值
补充说明① 一条jbpm4_deployment 记录需要对应4 条jbpm4_deployprop 记录,存储在KEY_里面:Langid 标识解析流程定义使用的 jpdl 的版本Pdid 流程定义的 id , 唯一标识一个流程Pdkey 流程的 key ,标识同一类流程Pdversion 标识流程的版本

表JBPM4_EXECUTION

表名流程实例表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK流程实例ID
CLASS_VARCHAR2(255 CHAR)N类型
DBVERSION_NUMBER(10)N步骤版本
ACTIVITYNAME_VARCHAR2(255 CHAR)Y节点名称
PROCDEFID_VARCHAR2(255 CHAR)Y流程定义ID
HASVARS_NUMBER(1)Y是否有变量值
NAME_VARCHAR2(255 CHAR)Y名称
KEY_VARCHAR2(255 CHAR)Y
ID_VARCHAR2(255 CHAR)YUK令牌ID
STATE_VARCHAR2(255 CHAR)Y令牌状态
SUSPHISTSTATE_VARCHAR2(255 CHAR)Y保存暂停之前状态
PRIORITY_NUMBER(10)Y优先级
HISACTINST_NUMBER(19)Y历史活动实例ID
PARENT_NUMBER(19)YFK(JBPM4_EXECUTION, DBID_)父实例
INSTANCE_NUMBER(19)YFK(JBPM4_EXECUTION, DBID_)流程实例
SUPEREXEC_NUMBER(19)YFK(JBPM4_EXECUTION, DBID_)父令牌
SUBPROCINST_NUMBER(19)YFK(JBPM4_EXECUTION, DBID_)子流程实例
PARENT_IDX_NUMBER(10)Y父实例序号
补充说明驱动流程运行,记录流程实例运行必须的信息

表JBPM4_HIST_ACTINST

表名流程活动(节点)实例表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK标识
CLASS_VARCHAR2(255 CHAR)Nactivity类型
DBVERSION_NUMBER(10)N版本
HPROCI_NUMBER( 19)YFK(JBPM4_HIST_PROCINST, DBID_)历史流程实例
TYPE_VARCHAR2(255 CHAR)Y活动实例类型
EXECUTION_VARCHAR2(255 CHAR)Y令牌
ACTIVITY_NAME_VARCHAR2(255 CHAR)Y活动实例名称
START_TIMESTAMP(6)Y开始名称
END_TIMESTAMP(6)Y结束时间
DURATION_NUMBER(19)Y节点停留时间
TRANSITION_VARCHAR2(255 CHAR)Y迁移路径
NEXTIDX_NUMBER(10)Y
HTASK_NUMBER(19)YFK(JBPM4_HIST_TASK, DBID_)对应的定义任务
补充说明流程运行中执行过的节点的记录,包括Task和State节点

JBPM4_HIST_DETAIL

表名流程历史详细表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK流程模版标识
CLASS_VARCHAR2(255 CHAR)N
DBVERSION_NUMBER(10)N版本
USERID_VARCHAR2(255 CHAR)Y用户ID
TIME_TIMESTAMP(6)Y时间
HPROCI_NUMBER(19)YFK(JBPM4_HIST_PROCINST, DBID_)对应的历史流程实例
HPROCIIDX_NUMBER(10)Y
HACTI_NUMBER(19)YFK(JBPM4_HIST_ACTINST, DBID_)对应的历史活动实例ID
HACTIIDX_NUMBER(10)Y
HTASK_NUMBER(19)YFK(JBPM4_HIST_TASK, DBID_)对应的任务
HTASKIDX_NUMBER(10)Y
HVAR_NUMBER(19)YFK(JBPM4_HIST_VAR, DBID_)对应的变量值
HVARIDX_NUMBER(10)Y
MESSAGE_CLOBY消息
OLD_STR_VARCHAR2(255 CHAR)Y老的String类型的值
NEW_STR_VARCHAR2(255 CHAR)Y新的String类型的值
OLD_INT_NUMBER(10)Y
NEW_INT_NUMBER(10)Y
OLD_TIME_TIMESTAMP(6)Y
NEW_TIME_TIMESTAMP(6)Y
PARENT_NUMBER(19)Y变量的父变量
PARENT_IDX_NUMBER(10)Y变量的父变量序号
补充说明历史信息的详细表,跟其他的历史表进行关联

JBPM4_HIST_PROCINST

表名流程实例历史表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK标识
DBVERSION_NUMBER(10)N版本
ID_VARCHAR2(255 CHAR)Y
PROCDEFID_VARCHAR2(255 CHAR)Y流程定义ID
KEY_VARCHAR2(255 CHAR)Y
START_TIMESTAMP(6)Y开始时间
END_TIMESTAMP(6)Y结束时间
DURATION_NUMBER(19)Y停留时间
STATE_VARCHAR2(255 CHAR)Y流程实例状态(活动,完成)
ENDACTIVITY_VARCHAR2(255 CHAR)Y是否完成
NEXTIDX_NUMBER(10)Y
补充说明历史流程实例相关信息

JBPM4_HIST_TASK

表名流程任务实例历史表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK标识
DBVERSION_NUMBER(10)N版本
EXECUTION_VARCHAR2(255 CHAR)Y令牌
OUTCOME_VARCHAR2(255 CHAR)Y路径名称
ASSIGNEE_VARCHAR2(255 CHAR)Y处理人
PRIORITY_NUMBER(10)Y优先级
STATE_VARCHAR2(255 CHAR)Y完成情况
CREATE_TIMESTAMP(6)Y创建时间
END_TIMESTAMP(6)Y完成时间
DURATION_NUMBER(19)Y任务节点停留时间
NEXTIDX_NUMBER(10)Y
SUPERTASK_NUMBER(19)YFK(JBPM4_HIST_TASK, DBID_)父任务
补充说明历史任务相关信息,与jbpm4_hist_actinst关联,单独的表减少了state节点相应字段的空闲和空间浪费

JBPM4_HIST_VAR

表名流程变量(上下文)历史表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK流程模版标识
DBVERSION_NUMBER(10)N版本
PROCINSTID_VARCHAR2(255 CHAR)Y对应运行的流程实例
EXECUTIONID_VARCHAR2(255 CHAR)Y活动实例ID
VARNAME_VARCHAR2(255 CHAR)Y变量名称
VALUE_VARCHAR2(255 CHAR)Y
HPROCI_NUMBER(19)YFK(JBPM4_HIST_PROCINST, DBID_)历史流程实例
HTASK_NUMBER(19)YFK(JBPM4_HIST_TASK, DBID_)历史任务
补充说明历史变量相关信息

JBPM4_ID_GROUP

表名组表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)N
DBVERSION_NUMBER(10)N
ID_VARCHAR2(255 CHAR)Y
NAME_VARCHAR2(255 CHAR)Y
TYPE_VARCHAR2(255 CHAR)Y
PARENT_NUMBER(19)Y
补充说明

JBPM4_ID_MEMBERSHIP

表名用户角色表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)N
DBVERSION_NUMBER(10)N
USER_NUMBER(19)Y
GROUP_NUMBER(19)Y
NAME_VARCHAR2(255 CHAR)Y
补充说明

JBPM4_ID_USER

表名用户表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)N
DBVERSION_NUMBER(10)N
ID_VARCHAR2(255 CHAR)Y
PASSWORD_VARCHAR2(255 CHAR)Y
GIVENNAME_VARCHAR2(255 CHAR)Y
FAMILYNAME_VARCHAR2(255 CHAR)Y
BUSINESSEMAIL_VARCHAR2(255 CHAR)Y
补充说明

JBPM4_JOB

表名定时表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK标识
CLASS_VARCHAR2(255 CHAR)N版本
DBVERSION_NUMBER(10)N
DUEDATE_TIMESTAMP(6)Y到期时间
STATE_VARCHAR2(255 CHAR)Y状态
ISEXCLUSIVE_NUMBER(1)Y是否可执行
LOCKOWNER_VARCHAR2(255 CHAR)Y锁定的参与者
LOCKEXPTIME_TIMESTAMP(6)Y锁定释放时间
EXCEPTION_CLOBY活动实例
RETRIES_NUMBER(10)Y重复次数
PROCESSINSTANCE_NUMBER(19)Y流程实例
EXECUTION_NUMBER(19)Y异常信息
CFG_NUMBER(19)YFK(JBPM4_LOB, DBID_)配置
SIGNAL_VARCHAR2(255 CHAR)Y信号
EVENT_VARCHAR2(255 CHAR)Y事件
REPEAT_VARCHAR2(255 CHAR)Y重复
补充说明作业相关

JBPM4_LOB

表名存储表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK主键
DBVERSION_NUMBER(10)N版本
BLOB_VALUE_BLOBY流程定义文件(xml、img、class)
DEPLOYMENT_NUMBER(19)YFK(JBPM4_DEPLOYMENT, DBID_)流程模版标识ID
NAME_CLOBY流程定义文件名
补充说明保存根据流程定义 xml 形成的二进制数据

JBPM4_PARTICIPATION

表名参与者表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK标识
DBVERSION_NUMBER(10)N版本
GROUPID_VARCHAR2(255 CHAR)Y组ID
USERID_VARCHAR2(255 CHAR)Y用户ID
TYPE_VARCHAR2(255 CHAR)Y类型
TASK_NUMBER(19)YFK(JBPM4_SWIMLANE, DBID_)任务ID
SWIMLANE_NUMBER(19)YFK(JBPM4_TASK,DBID_)对应泳道
补充说明办理人相关信息

JBPM4_PROPERTY

表名序列表
列名数据类型(精度范围)空/非空约束条件中文名
KEY_VARCHAR2(255 CHAR)N
VERSION_NUMBER(10)N
VALUE_VARCHAR2(255 CHAR)Y
补充说明为运行时需要持久化的对象生成dbid,其记录当前所有对象实例的最大值,每次需要生成dbid时,需要先获取该值,然后递增返回。

JBPM4_SWIMLANE

表名泳道表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK标识
DBVERSION_NUMBER(10)N版本
NAME_VARCHAR2(255 CHAR)Y泳道名
ASSIGNEE_VARCHAR2(255 CHAR)Y处理人
EXECUTION_NUMBER(19)YFK(JBPM4_EXECUTION, DBID_)活动实例
补充说明泳道相关信息

JBPM4_TASK

表名任务表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK主键
CLASS_CHAR(1 CHAR)N类型
DBVERSION_NUMBER(10)N版本
NAME_VARCHAR2(255 CHAR)Y活动节点名称
DESCR_CLOBY描述
STATE_VARCHAR2(255 CHAR)Y状态
SUSPHISTSTATE_VARCHAR2(255 CHAR)Y保存暂停之前状态
ASSIGNEE_VARCHAR2(255 CHAR)Y处理人
FORM_VARCHAR2(255 CHAR)Y表单地址
PRIORITY_NUMBER(10)Y优先级
CREATE_TIMESTAMP(6)Y创建时间
DUEDATE_TIMESTAMP(6)Y任务持续时间,表明任务应在多长时间内完成
PROGRESS_NUMBER(10)Y活动实例名
SIGNALLING_NUMBER(1)Y签收
EXECUTION_ID_VARCHAR2(255 CHAR)Y活动实例ID
ACTIVITY_NAME_VARCHAR2(255 CHAR)Y活动实例名称
HASVARS_NUMBER(1)Y是否有流程变量
SUPERTASK_NUMBER(19)YFK(JBPM4_TASK, DBID_)父任务
EXECUTION_NUMBER(19)Y活动实例
PROCINST_NUMBER(19)Y流程实例
SWIMLANE_NUMBER(19)YFK(JBPM4_SWIMLANE, DBID_)对应的泳道
TASKDEFNAME_VARCHAR2(255 CHAR)Y任务定义名
补充说明记录任务的相关信息

JBPM4_VARIABLE

表名上下文表
列名数据类型(精度范围)空/非空约束条件中文名
DBID_NUMBER(19)NPK标识
CLASS_VARCHAR2(255 CHAR)N版本
DBVERSION_NUMBER(10)N变量类型
KEY_VARCHAR2(255 CHAR)Y变量索引
CONVERTER_VARCHAR2(255 CHAR)Y数值转换器
HIST_NUMBER(1)Y对应的流程实例
EXECUTION_NUMBER(19)YFK(JBPM4_EXECUTION, DBID_)活动实例
TASK_NUMBER(19)YFK(JBPM4_TASK, DBID_)对应的任务
LOB_NUMBER(19)YFK(JBPM4_LOB, DBID_)
DATE_VALUE_TIMESTAMP(6)Y当值为date类型时,存值
DOUBLE_VALUE_FLOATY当值为double类型时,存值
CLASSNAME_VARCHAR2(255 CHAR)Y变量类名
LONG_VALUE_NUMBER(19)Y当值为long类型时,存值
STRING_VALUE_VARCHAR2(255 CHAR)Y当值为String类型时,存值
TEXT_VALUE_CLOBY当值为date类型时,存值
EXESYS_NUMBER(19)YFK(JBPM4_EXECUTION, DBID_)
补充说明记录传给流程的变量的相关信息

4.4 流程操作与数表交互说明

发布一个流程deploy

① jbpm4_deployment(流程定义):新增一条记录,记录新增的流程名称、时间、状态;

② jbpm4_lob(存储表): 新增一条记录,保存根据流程定义xml形成的二进制数据(同时也保存变量variable);

③ jbpm4_deployprop(流程定义属性表):新增四条记录,记录流程的属性,在“KEY_”里面记录一下四项内容:

Langid 标识解析流程定义使用的 jpdl 的版本;

Pdid 流程定义的 id , 唯一标识一个流程;

Pdkey 流程的 key ,标识同一类流程;

Pdversion 标识流程的版本。

zip包:(包含png和jpdl.xml)后

① JBPM4_DEPLOYMENT;

② JBPM4_DEPLOYPROP ;

③ JBPM4_LOB多两条。

开始一个流程startProcessInstanceByKey后

① jbpm4_execution(流程实例表):新增一条记录

② jbpm4_hist_procinst(流程实例历史表):新增一条记录

③ jbpm4_variable (上下表):新增一条记录

④ jbpm4_task (任务表):新增一条记录

⑤ jbpm4_hist_task(任务历史表):新增一条记录

⑥ jbpm4_hist_actinst (活动节点实例表):新增一条记录

填写申请信息

① jbpm4_variable(上下表) : 新增N条记录,根据表单信息决定

② jbpm4_task (任务表):新增一条记录

③ jbpm4_hist_task(任务历史表):新增一条记录

④ jbpm4_hist_actinst (活动节点实例表):新增一条记录

审批申请信息

1.同意:

① jbpm4_hist_actinst (活动节点实例表):新增一条记录

2.驳回:

① jbpm4_task (任务表):新增一条记录

② jbpm4_hist_task(任务历史表):新增一条记录

③ jbpm4_hist_actinst (活动节点实例表):新增一条记录

审批结束

① jbpm4_hist_actinst (活动节点实例表):新增一条记录

5 相关概念

流程定义:Process definition

一个流程的步骤说明。如一个请假流程、报销流程、借款流程等。是一个规则。

流程实例:Process instance

代表流程定义的一次执行。如张三昨天按照请假流程请了一次假。一个流程实例包括了所有运行的阶段,其中最典型的属性就是跟踪当前节点的指针。

Execution 执行

一般情况下,一个流程实例是一个执行树的根节点。

使用树状结构的原因在于,这一概念只有一条执行路径,使用起来更简单。业务API不需要了解流程实例和执行之间功能的区别。因此,API里只有一个执行类型来引用流程实例和执行。

6 流程图说明

6.0 快速上手

如图:在工程根路径下新建一个"Source Folder"文件夹

在这里插入图片描述

在上一步新建的文件夹里新建文件,如下:

在这里插入图片描述

建好后,打开 如下图所示:

在这里插入图片描述

画个简单的 图:

在这里插入图片描述

上图简单的说明:

当上图的活动部署并启动(部署和启动下文再细说)后,活动先到达部门审批,此时,只有"小李"(画流程图时指定的部门审批人)能看见自己的任务列表有该任务,流程下一步的 "经理"在自己的任务列表里是看不见该任务的。

当"小李"办理了该任务后,该任务将不会在"小李"的任务列表显示,而此时"经理"的任务列表里就有了该任务了。

"小李"办理了该任务后,该流程结束,该任务将不会在任何人的任务列表显示。

6.1 活动Activity / 节点Node

在这里插入图片描述

我们所用到的 活动 都在上图中了,下面介绍经常用到的活动的含义:

6.1.1 start 开始活动

在这里插入图片描述

代表流程的开始边界,一个流程有且只能有一个 start 活动。开始活动只能指定一个 Transition 。在流程实例启动后,会自动的使用这个唯一的 Transition 离开开始活动,到下一个活动。

6.1.2 end 结束活动

在这里插入图片描述

代表流程的结束边界,可以有多个,也可以没有。如果有多个,则达到任一个结束活动,整个流程就都结束了;如果没有,则到达最后面那个没有 Transition 的活动,流程就结束了。

6.1.3 task 任务活动

在这里插入图片描述

等待补充

6.1.4 decision 判断活动

在这里插入图片描述

等待补充

6.1.5 fork/join 分支/聚合活动

在这里插入图片描述

这是多个分支并行(同时)执行的,并且所有的分支 Execution 都到 join 活动后才向后执行。

展现在图中就是:task2、task3 和 task4 这三个任务都执行完毕,流程才继续往 task5 走。task2、task3 和 task4 中任意一个没有完成,任务都不会往下走。

注意: fork 和 join 是配合在一起使用的。

6.2 流转 Transition / 连线 (单向箭头)

6.2.1 开始活动

开始活动中只能有一个 Transition 。

6.2.2 结束活动

结束活动中没有 Transition 。

6.2.3 其他活动

其他活动中都是可以有1个或者n个 Transition 。

7 画图与配置

7.1 画图

完成以上的配置和概念了解后,我们来画图实际操作吧:

首先,我们画出如下图这样的一个流程图出来:(下图彩线箭头和汉语文字为辅助添加的,不包含在原流程图中)

在这里插入图片描述

7.2 配置

7.2.1 配置任务办理人

7.2.1.1 写死的方式配置任务办理人(不推荐)

当我们点击流程图中的每个节点,流程图下方都会出现如下图示的 属性编辑 框。

在这里插入图片描述

如果没有弹出该框。请在myeclipse 工具 ,按下图操作:

在这里插入图片描述

弹出该框后,我们看到该框有两个编辑栏可编辑:

点击 General 属性,可以在 右侧 输入框 输入 该节点的名称 ,输入名称后 该名称将会作为 该节点的name显示在流程图中和保存在数据库的相关表中(如下图示)。

在这里插入图片描述

点击 Assignment 属性,可以在右侧 输入框 配置该节点的

在这里插入图片描述

我们将本案例的流程图的 task1 和 task2 的任务办理人按照同样的方式分别设置成 “张三” 和 “李四” 。

7.2.1.2 #{}方式配置任务办理人

如下图操作:
在这里插入图片描述

然后,这样设置的是一个动态的,我们在完成 该节点的上一步 的任务的时候去设置该处的具体任务办理人。

具体代码在办理任务的时候添加。

7.2.1.3 实现接口方式配置任务办理人

该方式不需要在画图处设置,但是要在 流程图 的 xml 文件里设置。

在这里插入图片描述

我们此处是要设置 task4 的办理人,所以我们打开 流程图 的Source文件(如上图示):

找到 task4 的节点 ,加入如下节点,在该节点指定该处任务办理人的处理类的全路径名(完成后效果如下)。

 <task name="task4" g="512,360,92,52">
   <assignment-handler class="com.snow.config.User3AssignmentHandlerImpl">          </assignment-handler>
   <transition name="to join1" to="join1" g="-49,-22"/>
 </task>

注意:该类必须是实现了 AssignmentHandler 接口的类(如下)。

public class User3AssignmentHandlerImpl implements AssignmentHandler {
  private static final long serialVersionUID = 1L;
  @Override
  public void assign(Assignable assignable, OpenExecution execution) throws Exception {
    //  模拟从 数据库 拿到 的 相关人
    String userName = "王五";
    //  将 获取到的办理人 设置 给 该任务
    assignable.setAssignee(userName);  
  }
}

该类的调用时机是在 流程图 的流走到该节点自动调用。

7.2.1.4 方法指定方式分配任务办理人

此方式不需要在流程图中指定。需要在流程走到该节点之前的任何时机指定。

代码如下:

// 使用默认配置文件,先获取流程引擎
ProcessEngine processEngine = Configuration.getProcessEngine(); 
//  获取任务serviec
TaskService taskService = processEngine.getTaskService();
String tasjId = "1010101";
String userId = "赵六";
askService.assignTask(taskId, userId);

7.2.2 配置节点属性

7.2.2.1 判断节点(decision)

这是一个判断节点,流程走到这一步会根据该流程的特定属性进行判断,判断条件写在一个实现了 DecisionHandler 接口的类里,并在这里指定类的全限定类名。

在这里插入图片描述

实现类如下:

public class My3DecisionHandlerImpl implements DecisionHandler {

  private static final long serialVersionUID = 2L;
  
  //  根据指定的属性进行流程下一步的判断
  @Override
  public String decide(OpenExecution execution) { 
    //    获取申请数额 (这里的属性是在 流程到达该节点前指定的)
    Double money = Double.parseDouble((String) execution.getVariable("money"));
    //  重新分配流程下一步走向
    if(money > 100000){
      //  task6 节点名称 具体在画图时已指定  
      return "to task6";
    }
    //  end1 介绍节点名称 具体在画图时已指定
    return "to end1";
  }
}

该类控制下图的走向:

在这里插入图片描述

7.2.2.2 分支/聚合节点

在这里插入图片描述

如上图示:

流程完成 task2 后,会进入 fork(分支) 节点,流程一分为二:指向 task3 和 task4 。此时 task3 和 task4 节点任务办理人分别在他们的任务列表会看到该任务,只有当他们完成了各自的任务后,该流程才能继续往下走(task3 和 task4 任何一个节点任务没有完成,流程都不会再继续往下走),汇入 join 节点。

注意:区别于decision判断节点,分支与聚合节点本身是不需要额外的代码控制的,这两个节点本身自带的逻辑控制功能。

7.3 完成画图与配置后的效果

7.3.1 完成后的图

至此,我们的流程图 层面的配置就完了,流程图如下:

在这里插入图片描述

7.3.2 完成后配置的xml文件

流程图产生的xml文件如下(注意看配置相关节点节后与原xml文件的对比):

<?xml version="1.0" encoding="UTF-8"?><process name="test" xmlns="http://jbpm.org/4.4/jpdl">   <start g="472,32,48,48" name="start1">      <transition g="-46,-17" name="to task1" to="task1"/>   </start>   <task assignee="张三" g="450,112,92,52" name="task1">      <transition g="-47,-10" name="to task2" to="task2"/>   </task>   <decision g="472,608,48,48" name="exclusive1">   <handler class="com.snow.config.My3DecisionHandlerImpl" />      <transition g="6,-19" name="to end1" to="end1"/>      <transition g="-45,-17" name="to task6" to="task6"/>   </decision>   <task assignee="李四" g="450,196,92,52" name="task2">      <transition g="-44,-8" name="to fork1" to="fork1"/>   </task>   <task assignee="#{user3}" g="388,360,92,52" name="task3">      <transition g="-49,-22" name="to join1" to="join1"/>   </task>   <task g="512,360,92,52" name="task4">      <assignment-handler class="com.snow.config.User3AssignmentHandlerImpl"/>      <transition g="-49,-22" name="to join1" to="join1"/>   </task>   <fork g="472,280,48,48" name="fork1">      <transition g="-44,-15" name="to task3" to="task3"/>      <transition g="4,-10" name="to task4" to="task4"/>   </fork>   <join g="472,444,48,48" name="join1">      <transition g="-52,-22" name="to task5" to="task5"/>   </join>   <task g="450,524,92,52" name="task5">      <transition g="-79,-22" name="to exclusive1" to="exclusive1"/>   </task>   <end g="472,772,48,48" name="end1"/>   <task g="378,688,92,52" name="task6">      <transition g="-50,-22" name="to end1" to="end1"/>   </task></process>

8 操作API

8.1 部署流程

官方提供了2种方式的部署。

8.1.1 部署方式1-源文件

这种部署方式需要将 流程图文件 放在如下路径中(process文件与src文件同类型属于Source Folder),这样通过如下方式1部署时不会出现路径问题。

在这里插入图片描述

部署代码:

//部署方式1
@Test
void deploy1(){
   //使用默认配置文件,获取流程引擎
  ProcessEngine processEngine = Configuration.getProcessEngine(); 
   String deployId = processEngine.getRepositoryService()
    .createDeployment()
    .addResourceFromClasspath("aaa.jpdl.xml")
    .addResourceFromClasspath("aaa.png")
    .deploy();
  System.out.println("部署方式1 : deployId:" + deployId);
}

执行上面的代码后,控制台打印如下:

在这里插入图片描述

此时数据库表有如下变化:

数据定义表(jbpm4_deployment ) 多了一个字段 :id为 1500001 的流程定义,如下图示。

在这里插入图片描述

数据定义属性表(jbpm4_deployprop)也有变化,具体自己部署查看下。

8.1.2 部署方式2-zip包

以.zip压缩包的方式部署,我们将 画图产生的两个文件 打包成 .zip压缩包文件,放在如下图示的位置。

在这里插入图片描述

该种方式部署代码如下:

//  部署方式2 ZIP压缩文件
@Test  
public void deploy2(){
   ProcessEngine processEngine = Configuration.getProcessEngine(); 
  InputStream in = this.getClass().getClassLoader().getResourceAsStream("test.zip");
   ZipInputStream zipInputStream = new ZipInputStream(in);
   //  部署
   String deployId = processEngine.getRepositoryService()
     .createDeployment()
     .addResourcesFromZipInputStream(zipInputStream)
     .deploy();
   System.out.println("部署方式2 : deployId:" + deployId);
}

执行完上面部署代码后,控制台打印如下:

部署方式2 : deployId:1510001

注意:

就我们的demo而言:部署方式1 和 部署方式2 此时部署的其实是同一个流程,只是部署方式不一样。

所以其实是将同一个流程部署了两次。表现在数据库表中就是有两个版本的流程部署了。

版本号在第一次部署默认为1,后面部署相同的流程版本号会自动+1。

数据定义属性表(jbpm4_deployprop)数据:

在这里插入图片描述

8.2 查询流程实例

部署后就能查到流程定义。

8.2.1 查询所有

查询所有已经部署的流程定义,代码如下(会查询所有已经部署的流程定义,多版本也会一起返回)

//查询所有流程定义
@Test
public void findAll(){
   List<ProcessDefinition> list = processEngine.getRepositoryService()
     .createProcessDefinitionQuery()
     .orderAsc(ProcessDefinitionQuery.PROPERTY_KEY)
     .list();
   //  展示数据
   List<Map<String, String>> resultList = new ArrayList<Map<String,String>>();
   for(ProcessDefinition d : list){
     Map<String, String> map = new HashMap<>();
     map.put("id",d.getId());
     map.put("name",d.getName());
     map.put("key",d.getKey());
     map.put("version",String.valueOf(d.getVersion()));
     map.put("deploymentId",d.getDeploymentId());
     resultList.add(map);
   }
   System.out.println(resultList);
}

执行上面的查询代码马,控制台打印如下:

[{deploymentId=760001, name=applyFor, id=applyFor-1, version=1, key=applyFor}, {deploymentId=1440015, name=groupTest1125, id=groupTest1125-1, version=1, key=groupTest1125}, 
 {deploymentId=1350008, name=leave, id=leave-1, version=1, key=leave}, {deploymentId=1500001, name=test, id=test-1, version=1, key=test}, 
 {deploymentId=1510001, name=test, id=test-2, version=2, key=test}, 
 {deploymentId=990001, name=test11220846, id=test11220846-1, version=1, key=test11220846},
 {deploymentId=980009, name=testGroup2, id=testGroup2-1, version=1, key=testGroup2}]

8.2.2 查询所有最新版本的流程定义

会查询出每个Key下的最新版本,后面我们的启动就是按照指定key下的最新版本启动的

//  查询所有最新版本的流程定义
@Test  
public void findAllLastVersion(){
   List<ProcessDefinition> list = processEngine.getRepositoryService()
     .createProcessDefinitionQuery()
     .orderAsc(ProcessDefinitionQuery.PROPERTY_VERSION)
     .list();

   //  过滤 过滤出最新版本
   Map<String, ProcessDefinition> mapBefore = new HashMap<String, ProcessDefinition>();
   for(ProcessDefinition definition : list){
     mapBefore.put(definition.getKey(),definition);
   }

   //  展示数据
   List<Map<String, String>> resultList = new ArrayList<Map<String,String>>();
   for(ProcessDefinition d : mapBefore.values()){
     Map<String, String> map = new HashMap<>();
     map.put("id",d.getId());
     map.put("name",d.getName());
     map.put("key",d.getKey());
     map.put("version",String.valueOf(d.getVersion()));
     map.put("deploymentId",d.getDeploymentId());
     resultList.add(map);
   }
   System.out.println(resultList);
}


执行上面的查询代码后,控制台打印如下:

[{deploymentId=990001, name=test11220846, id=test11220846-1, version=1, key=test11220846}, 
{deploymentId=1510001, name=test, id=test-2, version=2, key=test}, 
{deploymentId=980009, name=testGroup2, id=testGroup2-1, version=1, key=testGroup2}, {deploymentId=1350008, name=leave, id=leave-1, version=1, key=leave}, {deploymentId=1440015, name=groupTest1125, id=groupTest1125-1, version=1, key=groupTest1125}, 
{deploymentId=760001, name=applyFor, id=applyFor-1, version=1, key=applyFor}]

注意与查询所有的结果比较:key 为 test 的结果只有一条了,且version=2。

8.3 删除流程定义

删除流程定义可以按照id和key删除。

8.3.1 按照id删除(有关联信息会抛异常)

// 删除流程定义  
@Test
public void deleteById(){
   String deploymentId = "1500001";
   ProcessEngine processEngine = Configuration.getProcessEngine(); 
   //  有关联信息,抛异常
   processEngine.getRepositoryService().deleteDeployment(deploymentId);   
}

上述这种删除方法,如果该流程id对应的流程有关联信息,将会抛异常。

8.3.2 按照id删除(会删除关联信息)

// 删除流程定义  
@Test
public void deleteById(){
   String deploymentId = "1500001";
   ProcessEngine processEngine = Configuration.getProcessEngine(); 
   //  有关联信息,会级联删除
  processEngine.getRepositoryService().deleteDeploymentCascade(deploymentId);  
}

上述这种删除方法,如果该流程id对应的流程有关联信息,会级联删除!

8.3.3 按照key删除

//  删除流程定义  按照key
@Test
public void deleteByKey(){
   String key = "b";
   List<ProcessDefinition> list = processEngine.getRepositoryService()
     .createProcessDefinitionQuery()
     .processDefinitionKey(key)
     .list();
   //  遍历  删除
   if( list != null && list.size() > 0){
     for(ProcessDefinition processDefinition : list){
       System.out.println(processDefinition.getId());
   ProcessEngine processEngine = Configuration.getProcessEngine();              processEngine.getRepositoryService().
     deleteDeploymentCascade(processDefinition.getDeploymentId());
     }
   }
}

该方式会将该key下的所有实例删除。

8.4 获取部署时的文件资源

8.4.1 获取部署时的文件资源方式1

该方式要指定jbpm4_deployment表 DBID 和 jbpm4_lob 表中deplotmentId对应的name_的值

// 获取部署时的文件资源(查看流程图)

@Test  
public void get() throws Exception{
   ProcessEngine processEngine = Configuration.getProcessEngine(); 
   //  jbpm4_deployment表 DBID
   String deplotmentId = "1510001";   
   //  jbpm4_lob 表中deplotmentId对应的name_的值
   String resourceName = "test.png";  
   //  获取所有资源名称
   Set<String> names = processEngine.getRepositoryService().getResourceNames(deplotmentId);
   for(String name : names){
     System.out.println(name);
   }

   InputStream in = processEngine.getRepositoryService().getResourceAsStream(deplotmentId, resourceName);

   //  输出到本地文件 (路径自己指定,但要注意路径中包含的文件夹都存在)
   OutputStream outputStream = new FileOutputStream("d:/photoAlbum/process-" + deplotmentId +".png");
   for(int b = -1;(b = in.read()) != -1;){
     outputStream.write(b);
   }
   in.close();
   outputStream.close();
}

执行上述代码,会在我们指定的路径下得到如下图片:就是我们部署时候的流程图。

在这里插入图片描述

8.4.2 获取部署时的文件资源方式2

该方式要指定 jbpm4_execution 表中的 PROCDEFID 字段。

@Test  //  得到图片资源2
public void get2() throws IOException{
   //  jbpm4_execution 表中的 PROCDEFID
   String processDefinitionId = "test-2";
   ProcessDefinition processDefinition = processEngine.getRepositoryService()
     .createProcessDefinitionQuery()
     .processDefinitionId(processDefinitionId)
     .uniqueResult();

   InputStream in = processEngine.getRepositoryService().getResourceAsStream(processDefinition.getDeploymentId(), processDefinition.getImageResourceName());
   //    输出到本地文件
   OutputStream outputStream = new FileOutputStream("d:/photoAlbum/process/deplotmentImg/" + processDefinitionId + ".png");
   for(int b = -1;(b = in.read()) != -1;){
     outputStream.write(b);
   }
   in.close();
   outputStream.close();
}

执行上述代码,会在我们指定的路径下得到如下图片:就是我们部署时候的流程图。

在这里插入图片描述

8.5 启动实例

8.5.1 按照key启动(不加参数)

@Test  //  启动 -- 简单的启动
public void startProcessInstace(){
   ProcessEngine processEngine = Configuration.getProcessEngine(); 
   //  会启动该key下的最新版本的流程
   ProcessInstance instance = processEngine.getExecutionService().startProcessInstanceByKey("test");
   System.out.println(instance.getId());
   System.out.println(instance.getName());
   System.out.println(instance.getIsProcessInstance());
   System.out.println(instance.getKey());
   System.out.println(instance.getState());
}

注意:这里出现了 key 的概念。回顾我们在上一步画流程图的时候,并没有指定key,但是 我们在创建流程图的时候对文件进行了命名,如果不指定key,那么默认的key就和name同名。

执行上面的启动代码后,控制台打印如下:

在这里插入图片描述

8.5.2 按照key启动(加入参数)

//  启动 -- 并加入一些参数
@Test  
public void startProcessInstance(){
   String processKey = "test";
   Map<String, String> variableMap = new HashMap<String, String>();
   String username = "JackMa";//  申请人 这里的数据是从服务器过去当前登录人
   variableMap.put("申请人", username); 
   //  实际数据从表单获取 
   variableMap.put("申请事由", "扩展东南亚业务");
   variableMap.put("申请金额", String.valueOf(200000));//  前端填写必须是数字,后台转String
   //  将date转换为字符串
   variableMap.put("申请时间", DateUtil.convertDate2String(new Date(), null));
   variableMap.put("备注", "XXX");
   variableMap.put("最新进度",username+"-提交了申请");
   variableMap.put("状态", "进行中...");
   ProcessEngine processEngine = Configuration.getProcessEngine(); 
   ProcessInstance instance = processEngine.getExecutionService().startProcessInstanceByKey(processKey, variableMap);
   System.out.println(instance.getId());
}

执行启动代码,控制台打印如下:

在这里插入图片描述

此时 数据库中 jbpm4_variable 表就会有以下数据:

在这里插入图片描述

8.5.3 启动流程实例的说明

API也提供了按照id的启动方式,但是在实际业务中用不到。(因为不会去启动一个作废的审批流程)

在这里插入图片描述

8.6 查询任务

8.6.1 查询所有未办理任务

//  查询所有未办理的任务列表
@Test  
public void getAllTask(){
   List<Task> list = processEngine.getTaskService()
     .findPersonalTasks(null);
   for(Task task : list){
     System.out.println("id="+task.getId() + 
              ",name=" + task.getName() + 
              ",assignee="+task.getAssignee() + 
              ",createTime="+task.getCreateTime());
   }
}

上述方法会查询出所有未办理的任务:

在这里插入图片描述

8.6.2 查询个人未办理任务

//  查询我的未办理的任务列表
@Test  
public void getTaskByName(){
   String userName = "张三";
   List<Task> list = processEngine.getTaskService().findPersonalTasks(userName);
   for(Task task : list){
     System.out.println("id="+task.getId() + 
              ",name="+task.getName() + 
              ",assignee="+task.getAssignee() + 
              ",createTime="+task.getCreateTime());
     System.out.println(task.getExecutionId());
   }
}

查询结果:

在这里插入图片描述

可以看出:张三 这个用户有两条未办理的任务。其中executionId去掉 " key." 就会得到 一个新的字段。

例如:executionId=test.1530001 ----> 153001 会对应到 jbpm4_variable 表中的 EXECUTION 字段 , 通过该字段又能得到该表下的参数信息 (该参数信息是在启动实例的时候指定的,后续该数据将会是从前台申请表单拿到,并在启动时加入)。

在这里插入图片描述

8.6.3 查询个人的待办组任务

目前为止我们还没有指定组任务(组任务在 8.10),所以该处查询暂时会是空。

//  找到个人 的 分组 任务
@Test  
public void findGroupTasksByUser(){
   String user = "小明";
   List<Task> tasks = processEngine.getTaskService()
     .createTaskQuery()
     .candidate(user)
     .list();
   System.out.println(tasks.size());
   for(Task task : tasks){
     System.out.println(task.getId() + task.getName() + task.getAssignee());
   }
}

8.7 办理任务

8.7.1 办理个人任务

办理前数据表中:

在这里插入图片描述

办理任务:

//  办理个人任务
@Test
public void comPeletePersonTask111(){
   String taskId = "1520002";
   String user = "张三";
   List<Task> list = processEngine.getTaskService().findPersonalTasks(user);
   System.out.println(list.size());
   if( list == null || list.size() < 1){
     //  throw ... 
     System.out.println("该用户当前没有可以办理的任务!");
     return;
   }
   for(Task task : list){
     if(user.equals(task.getAssignee()) && taskId.equals(taskId)){
       // 办理任务
       processEngine.getTaskService().completeTask(taskId);
       break;
     }
   }
}

办理后数据表:
在这里插入图片描述

8.7.2 办理个人组任务

个人组任务:组任务节点的办理人不是一个人,而是一组拥有相同权限的人(设置组任务办理人在8.10.1)。

组任务不能直接办理,需要先将该组任务 拾取 到个人任务中。这样该组任务就变成了个人任务,此时办理方法同8.7.1。

拾取任务:

@Test
public void ban(){
   String taskId = "1470004";
   String user = "小红";
   //  拾取前 判断下 该组任务的办理用户中是否有 该用户
   //  判断 略...
   processEngine.getTaskService().takeTask(taskId, user);
}
//  拾取任务后 该组任务就变为自己的任务了 办理 同 8.7.1
//  办理 略...

8.8 驳回任务

//  驳回申请
@Test  
public void jujue(){
   String taskId = "410001";
   Task task = processEngine.getTaskService().getTask(taskId);
   System.out.println(task.getExecutionId());
   //  在驳回任务前最好先做个判断,只能驳回属于自己的任务
   //  判断 略...
   processEngine.getExecutionService()
     .endProcessInstance(task.getExecutionId(),ProcessInstance.STATE_ENDED);
}

8.9 流程变量

流程变量设置的值的作用域是整个流程(流程启动到流程结束,流程变量在流程结束后会自动从数据库表删除)。

流程变量 会保存在 jbpm4_variable 表中。

8.9.2 设置流程变量

//  设置流程变量
@Test
public void testSetVariables(){
   String executionId = "";
   String taskId = "";
   String name = "";
   Object value = "";
   Map<String, Object> variableMap = new HashMap<String, Object>();
   String processDefinitionKey = "";

   //  以下 设置 流程变量的方式 任选其一就行

   //  根据 Execution 设置一个流程变量
   processEngine.getExecutionService().setVariable(executionId, name, value);
   //  根据 Execution 设置多个流程变量
   processEngine.getExecutionService().setVariables(executionId, variableMap);
   //  根据 Task 设置多个流程变量(放入map)
   processEngine.getTaskService().setVariables(taskId, variableMap);

   //  启动时候 加入流程变量
   processEngine.getExecutionService().startProcessInstanceByKey(processDefinitionKey, variableMap);

   //  办理指定任务 并 加入 参数
   processEngine.getTaskService().completeTask(taskId, variableMap);
}

8.9.3 获取流程变量

//  获取流程变量
@Test
public void testGetVariables(){
   String executionId = "";
   String taskId = "";
   String variableName = "";
   //  根据 Execution获取指定名称的一个流程变量
   processEngine.getExecutionService().getVariable(executionId, variableName);

   //  根据 Execution获取所有流程变量
   processEngine.getExecutionService().getVariableNames(executionId);

   //  根据 Execution获取指定名称的所有流程变量
   Set<String> variableNames1 = null;
   processEngine.getExecutionService().getVariables(executionId, variableNames1);

   //  同上
   processEngine.getTaskService().getVariable(taskId, variableName);

   processEngine.getTaskService().getVariableNames(taskId);
  Set<String> variableNames2 = null;
   processEngine.getTaskService().getVariables(taskId, variableNames2);
}

所有的流程变量 都在 jbpm4_variable 表中可以查看。

8.10 组任务

8.10.1 组任务的分配

8.10.1.1 写死的方式指定

该方式不推荐

在这里插入图片描述

人名与人名之间用 英文逗号 隔开。

8.10.1.2 实现AssignmentHandler接口指定

在.xml文件配置如下:

 <task name="组任务2" g="347,280,92,52">
    <assignment-handler class="com.snow.config.Group11AssignmentHandler">
     </assignment-handler>
    <transition name="to end1" to="end1" g="-50,-22"/>
</task>

类实现:

public class Group11AssignmentHandler implements AssignmentHandler {

  private static final long serialVersionUID = 11L;

  @Override
  public void assign(Assignable assignable, OpenExecution execution) throws Exception {
    // 获取 该分组任务的 候选人  ooo_task2_users流程变量是在流程走到该节点前指定的
    String vairableName = "ooo_task2_users";   
    String[] users = (String[]) execution.getVariable(vairableName);
    
    //  将 人员 分配 给 组任务
    for(String user : users){
      assignable.addCandidateUser(user);
    }
  }
}

8.10.2 查询自己的组任务

//  查询自己的组任务
@Test  
public void findGroupTasksByUser(){
   String user = "小明";
   List<Task> tasks = processEngine.getTaskService()
     .createTaskQuery()
     .candidate(user)
     .list();
   System.out.println(tasks.size());
   for(Task task : tasks){
     System.out.println(task.getId() + task.getName() + task.getAssignee());
   }
}

8.10.3 办理自己的组任务

同 8.7.2


getExecutionService().getVariables(executionId, variableNames1);

   //  同上
   processEngine.getTaskService().getVariable(taskId, variableName);

   processEngine.getTaskService().getVariableNames(taskId);
  Set<String> variableNames2 = null;
   processEngine.getTaskService().getVariables(taskId, variableNames2);
}

所有的流程变量 都在 jbpm4_variable 表中可以查看。

8.10 组任务

8.10.1 组任务的分配

8.10.1.1 写死的方式指定

该方式不推荐

人名与人名之间用 英文逗号 隔开。

8.10.1.2 实现AssignmentHandler接口指定

在.xml文件配置如下:

 <task name="组任务2" g="347,280,92,52">
    <assignment-handler class="com.snow.config.Group11AssignmentHandler">
     </assignment-handler>
    <transition name="to end1" to="end1" g="-50,-22"/>
</task>

类实现:

public class Group11AssignmentHandler implements AssignmentHandler {

  private static final long serialVersionUID = 11L;

  @Override
  public void assign(Assignable assignable, OpenExecution execution) throws Exception {
    // 获取 该分组任务的 候选人  ooo_task2_users流程变量是在流程走到该节点前指定的
    String vairableName = "ooo_task2_users";   
    String[] users = (String[]) execution.getVariable(vairableName);
    
    //  将 人员 分配 给 组任务
    for(String user : users){
      assignable.addCandidateUser(user);
    }
  }
}

8.10.2 查询自己的组任务

//  查询自己的组任务
@Test  
public void findGroupTasksByUser(){
   String user = "小明";
   List<Task> tasks = processEngine.getTaskService()
     .createTaskQuery()
     .candidate(user)
     .list();
   System.out.println(tasks.size());
   for(Task task : tasks){
     System.out.println(task.getId() + task.getName() + task.getAssignee());
   }
}

8.10.3 办理自己的组任务

同 8.7.2


在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/546594.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【学习笔记】Rider调试unity【 联调、断点调试等】(决定弃用vscode了)

目录 一 弃用vscode原委二 Rider调试Unity2.1 启动调试2.2 pausepoint 暂停点2.2.1 使用pausepoint2.2.2 pausepoint&#xfeff;与breakpoint的区别 2.3 不同run configuration区别 三 Rider编辑3.1 补充 四 总结 转载请注明出处&#xff1a;&#x1f517;https://blog.csdn.n…

头歌计算机组成原理实验—运算器设计(4)第4关:16位快速加法器设计

第4关&#xff1a;16位快速加法器设计 实验目的 帮助学生理解成组进位产生函数&#xff0c;成组进位传递函数的概念&#xff0c;熟悉 Logisim 平台子电路的概念&#xff0c;能利用前述实验封装好的4位先行进位子电路以及4位快速加法器子电路构建16位、32位、64位快速加法器&a…

Android 12.0 原生SystemUI下拉通知栏UI背景设置为圆角背景的定制(一)

1.前言 在12.0的系统rom定制化开发中,在原生系统SystemUI下拉状态栏的通知栏的背景是白色四角的背景,由于在产品设计中,需要把四角背景默认改成圆角背景,所以就需要分析系统原生下拉通知栏的每条通知的默认背景,然后通过systemui的通知流程,设置默认下拉状态栏UI中的通知…

java+nodejs+vue+python+php家教信息管理系统

任何网友都可以自由地查看、搜索、发布该家教信息平台的信息。该平台是区别于传统的家教中介的服务平台。学生可以免费查看网站上的家教信息&#xff0c;挑选适合自己的家教&#xff1b;教师可以免费查看网站上的需求信息&#xff0c;挑选适合自己的学生&#xff1b;学生可以发…

chatgpt赋能Python-python3安装scrapy

Python3安装Scrapy&#xff1a;提高爬虫效率的关键 如果你正在从事数据科学、数据分析工作&#xff0c;或者需要收集并存储某些特定网站的数据&#xff0c;Scrapy是一个值得尝试的Python3框架。Scrapy是一个开源的Web爬虫框架&#xff0c;可以方便、高效、快速地对数据进行收集…

Rust每日一练(Leetday0005) 罗马数字、公共前缀、三数之和

目录 13. 罗马数字转整数 Roman to Integer &#x1f31f; 14. 最长公共前缀 Longest Common Prefix &#x1f31f; 15. 三数之和 3Sum &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Rust每日一练 专栏 Golang每日一练 专栏 Python每日…

Qt/QML编程学习之心得:颜色编码方案RGB+YUV+HSI等(八)

说到Human-Machine Interaction 人机交互界面或者说GUI,那么第一反映可能是窗口、各种控件、各种图片,但是所有这些都还需要一个更底层的内容,那就颜色。不管是窗口还是控件,颜色是其最基本的一个属性。 牛顿三棱镜色散实验,发现光的色彩奥妙:当一束白光通过三棱镜时,它…

chatgpt赋能Python-python3控制摄像头拍照

Python3 控制摄像头拍照 介绍 Python3 是一种高级编程语言&#xff0c;被广泛应用于机器学习、人工智能、Web 开发等领域。控制摄像头拍照是 Python3 中非常常见的需求&#xff0c;例如监控、照片拍摄等等。 如何控制摄像头拍照 在 Python3 中&#xff0c;我们可以利用 Ope…

【高效科研工具(一):chatGPT(各种高效网站大集合)】

高效科研工具&#xff08;一&#xff09;&#xff1a;chatGPT&#xff08;各种高效网站大集合&#xff09; 目录 0、前言 1、chatGPT介绍 2、chatGPT官网 3、各种衍生网站&#xff08;&#x1f929;&#x1f929;&#x1f929;&#x1f929;重头戏&#xff01;&#xff01;&a…

插入排序、选择排序、冒泡排序小结(45)

小朋友们好&#xff0c;大朋友们好&#xff01; 我是猫妹&#xff0c;一名爱上Python编程的小学生。 和猫妹学Python&#xff0c;一起趣味学编程。 今日主题 插入排序、选择排序、冒泡排序有什么区别&#xff1f; 原理不同 插入排序是将未排序的元素逐个插入到已排序序列中…

王道考研——计算机网络1.1计算机网络概述

文章目录 0.认识计算机网络1. 计算机网络体系结构1.1概念及功能计算机网络的概念计算机网络的功能计算机网络的发展总结 1.2组成与分类计算机网络的组成计算机网络的分类总结 1.3标准化工作及相关组织&#xff08;408大纲已删&#xff09;标准化工作标准化工作的相关组织总结 1…

总结856

学习目标&#xff1a; 月目标&#xff1a;5月&#xff08;张宇强化前10讲&#xff0c;背诵15篇短文&#xff0c;熟词僻义300词基础词&#xff09; 周目标&#xff1a;张宇强化前3讲并完成相应的习题并记录&#xff0c;英语背3篇文章并回诵 每日必复习&#xff08;5分钟&#…

chatgpt赋能Python-python3怎么降到2

Python3如何降级到Python2 Python3是Python语言的最新版本&#xff0c;但是一些旧的项目或者库可能只支持Python2&#xff0c;这就需要将Python3降级到Python2。本文将介绍如何在MacOS和Windows系统上进行Python3到Python2的降级&#xff0c;并提供详细的步骤和注意事项。 Ma…

chatgpt赋能Python-python3自定义排序

Python3自定义排序 在Python3中&#xff0c;可以使用内置的sorted()函数或list.sort()方法对列表进行排序。这些方法通常基于默认排序规则&#xff0c;即按照元素的字符串表示进行排序。不过&#xff0c;有时候我们需要按照自己定义的规则对列表进行排序。这就需要使用自定义排…

Windows免安装MySQL8.0

Windows免安装MySQL8.0 Windows 上的 MySQL 分为安装版和免安装版。 本文介绍如何在 Windows 上配置免安装版的 MySQL 8.0。 1、下载并安装 VC_redist.x64.exe Windows 版的 MySQL 8.0 依赖 Microsoft Visual C 2019 Redistributable Package&#xff08;VC_redist.x64.exe…

【c++ • STL】初步认识什么是 STL 标准库

&#x1f680; 个人简介&#xff1a;CSDN「博客新星」TOP 10 &#xff0c; C/C 领域新星创作者&#x1f49f; 作 者&#xff1a;锡兰_CC ❣️&#x1f4dd; 专 栏&#xff1a;从零开始的 c 之旅&#x1f308; 若有帮助&#xff0c;还请关注➕点赞➕收藏&#xff0c;不行的…

html网页制作(一)基础

之前做web的时候发现&#xff0c;有些页面的源代码&#xff0c;我都不能&#xff0c;完全看懂&#xff0c;所以就像学习一下 一.html是什么&#xff1f; HTML的全称为超文本标记语言&#xff0c;是一种标记语言。它包括一系列标签&#xff0e;通过这些标签可以将网络上的文档格…

深入浅出JWT

什么是JWT? JWT的本质就是一个字符串&#xff0c;它是将用户信息保存到一个Json字符串中&#xff0c;然后进行编码后得到一个JWT token&#xff0c;并且这个JWT token带有签名信息&#xff0c;接收后可以校验是否被篡改&#xff0c;所以可以用于在各方之间安全地将信息作为Js…

chatgpt赋能Python-python3__2

Python3 中的位运算符 在 Python3 中&#xff0c;位运算符是用来执行二进制位操作的操作符。这些操作符允许我们对二进制位进行一些有用的操作&#xff0c;如位移、按位与、按位或、按位取反等。 在本文中&#xff0c;我们将介绍 Python3 中的位运算符 <<&#xff0c;也…

查看电脑的BIOS版本的五种方法

查看主板BIOS版本的五种方法 概述1. 在 BIOS 中查看2. 使用 DirectX 诊断工具3. 使用 CPU-Z 中查看4. 在 CMD 中查看&#xff08;一&#xff09;5. 在 CMD 中查看 &#xff08;二&#xff09;结束语 概述 BIOS是 Basic Input Output System 的缩略词&#xff0c;直译就是 **基…