Fork me on GitHub

Activiti(3)--数据模型设计

数据表分类 描述
ACT_GE_* 通用数据表
ACT_RE_* 流程定义存储表
ACT_ID_* 身份信息表
ACT_RU_* 运行时数据库表
ACT_HI_* 历史数据库表, 为了保证运行时数据尽可能少, 流程执行完就会将相关数据迁移到历史表中
  • 核心引擎: activiti.mysql.create.engine.sql
  • 历史数据: activiti.mysql.create.history.sql
  • 身份数据: activiti.mysql.create.identity.sql

Activiti 除了核心引擎以外, 其他都是可选的.

首先创建 ACT_GE_PROPERTY 表, 并写入:

  1. schema.version(schema 版本)
  2. schema.history(schema 历史)
  3. next.dbid(自增 id)
    三条记录

1. 通用数据库

数据表分类 描述
ACT_GE_PROPERTY 属性表(保存流程引擎的 kv 键值属性)
ACT_GE_BYTEARRAY 资源表(存储流程定义相关的资源, 如 xml, 流程定义图)

1.1. ACT_GE_PROPERTY

对应实体类 org.activiti.engine.impl.persistence.entity.PropertyEntityImpl

image

1.2 ACT_GE_BYTEARRAY

对应实体类 org.activiti.engine.impl.persistence.entity.ByteArrayEntityImpl

image

其中 GENERATED_ 字段标识该资源文件是自动生成还是人工上传

如果不想添加身份信息相关数据库和历史数据相关数据库, 可以在配置中显式指定

1
2
3
4
5
6
7
8
9
10
11
<bean id="processEngineConfiguration"
class="org.activiti.engine.impl.cfg.StandaloneInMemProcessEngineConfiguration">
<property name="jdbcUrl" value="jdbc:h2:mem:activiti;DB_CLOSE_DELAY=1000;MVCC=TRUE"/>
<property name="jdbcDriver" value="org.h2.Driver"/>
<property name="jdbcUsername" value="sa"/>
<property name="jdbcPassword" value=""/>
<!-- 不创建 ACT_ID_* 相关的表 -->
<property name="dbIdentityUsed" value="false"/>
<!-- 不创建 ACT_HI_* 相关的表 -->
<property name="dbHistoryUsed" value="false"/>
</bean>

2. 流程定义存储表

数据表分类 描述
ACT_RE_DEPLOYMENT 流程部署记录表
ACT_RE_PROCDEF 流程定义信息表
ACT_RE_MODEL 模型信息表(用于 web 设计器)
ACT_PROCDEF_INFO 流程定义动态改变信息表

2.1. ACT_RE_DEPLOYMENT

对应实体 org.activiti.engine.impl.persistence.entity.DeploymentEntityImpl

关键字段 描述
ID_ 主键
NAME_ 名称
CATEGORY_ 分类
TENANT_ID_ 多租户标志
DEPLOY_TIME_ 部署时间
KEY_ 标志 key
ENGINE_VERSION_ 兼容版本, 如果使用 Activiti5, 在升级到6后会有特殊标志

2.2 ACT_RE_PROCDEF

对应实体 org.activiti.engine.impl.persistence.entity.ProcessDefinitionEntityImpl

关键字段 描述
DEPLOYMENT_ID_ 关联部署 id
RESOURCE_NAME_ 流程定义资源名称
DGRM_RESOURCE_NAME_ 流程图片资源名称
HAS_START_FORM_KEY_ 是否存在开始表单标志
HAS_GRAPHICAL_NOTATION_ 是否有图形信息
SUSPENSION_STATE_ 挂起状态 1 正常, 2 挂起

2.3. 测试代码

1
2
3
4
5
6
7
8
@Test
public void testDeploy() {
activitiRule.getRepositoryService()
.createDeployment()
.name("二次审批流程")
.addClasspathResource("org/destiny/activiti/SecondApprove.bpmn20.xml")
.deploy();
}

ACT_RE_DEPLOYMENT 表内容:

mysql> select * from ACT_RE_DEPLOYMENT \G;
*************************** 1. row ***************************
            ID_: 1
          NAME_: 二次审批流程
      CATEGORY_: NULL
           KEY_: NULL
     TENANT_ID_:
   DEPLOY_TIME_: 2018-12-11 09:11:27.538
ENGINE_VERSION_: NULL

ACT_RE_PROCDEF 表内容:

mysql> select * from ACT_RE_PROCDEF \G;
*************************** 1. row ***************************
                    ID_: SecondApprove:1:4
                   REV_: 1
              CATEGORY_: http://www.activiti.org/test
                  NAME_: 二级审批
                   KEY_: SecondApprove
               VERSION_: 1
         DEPLOYMENT_ID_: 1
         RESOURCE_NAME_: org/destiny/activiti/SecondApprove.bpmn20.xml
    DGRM_RESOURCE_NAME_: org/destiny/activiti/SecondApprove.SecondApprove.png
           DESCRIPTION_: NULL
    HAS_START_FORM_KEY_: 0
HAS_GRAPHICAL_NOTATION_: 1
      SUSPENSION_STATE_: 1
             TENANT_ID_:
        ENGINE_VERSION_: NULL
        
        

可以看到, 其中 HAS_START_FORM_KEY_ 为 0, DESCRIPTION_ 为 NULL, 二者都需要去流程定义文件中设置

  • HAS_START_FORM_KEY_ 需要在 startEvent 中设置 actviti:formKey;
  • DESCRIPTION 需要设置 documentation

修改流程定义文件:

1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://www.omg.org/spec/BPMN/20100524/MODEL" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:activiti="http://activiti.org/bpmn"
xmlns:bpmndi="http://www.omg.org/spec/BPMN/20100524/DI"
xmlns:omgdc="http://www.omg.org/spec/DD/20100524/DC" xmlns:omgdi="http://www.omg.org/spec/DD/20100524/DI"
typeLanguage="http://www.w3.org/2001/XMLSchema" expressionLanguage="http://www.w3.org/1999/XPath"
targetNamespace="http://www.activiti.org/test">
<process id="SecondApprove" name="二级审批" isExecutable="true">
<documentation>审批流程描述</documentation>
<startEvent id="startEvent" name="开始" activiti:formKey="/process/form/key"></startEvent>
<userTask id="submitApprove" name="填写申请信息">

然后重新部署即可看到:

mysql> select * from ACT_RE_PROCDEF \G;
*************************** 1. row ***************************
                    ID_: SecondApprove:1:4
                   REV_: 1
              CATEGORY_: http://www.activiti.org/test
                  NAME_: 二级审批
                   KEY_: SecondApprove
               VERSION_: 1
         DEPLOYMENT_ID_: 1
         RESOURCE_NAME_: org/destiny/activiti/SecondApprove.bpmn20.xml
    DGRM_RESOURCE_NAME_: org/destiny/activiti/SecondApprove.SecondApprove.png
           DESCRIPTION_: NULL
    HAS_START_FORM_KEY_: 0
HAS_GRAPHICAL_NOTATION_: 1
      SUSPENSION_STATE_: 1
             TENANT_ID_:
        ENGINE_VERSION_: NULL
*************************** 2. row ***************************
                    ID_: SecondApprove:2:2504
                   REV_: 1
              CATEGORY_: http://www.activiti.org/test
                  NAME_: 二级审批
                   KEY_: SecondApprove
               VERSION_: 2
         DEPLOYMENT_ID_: 2501
         RESOURCE_NAME_: org/destiny/activiti/SecondApprove.bpmn20.xml
    DGRM_RESOURCE_NAME_: org/destiny/activiti/SecondApprove.SecondApprove.png
           DESCRIPTION_: 审批流程描述
    HAS_START_FORM_KEY_: 0
HAS_GRAPHICAL_NOTATION_: 1
      SUSPENSION_STATE_: 1
             TENANT_ID_:
        ENGINE_VERSION_: NULL
        
        

ACT_RE_PROCDEF 是基于 KEY_ 去升级版本号, 当原有的 key 已经存在, 就会升级版本号, 其中 KEY_, VERSION_, TENANT_ID_ 共同组成一个唯一键

3. 身份数据表设计

数据表设计 描述
ACT_ID_USER 用户的基本信息
ACT_ID_INFO 用户的扩展信息
ACT_ID_GROUP 群组
ACT_ID_MEMBERSHIP 用户与群组关系

3.1. 用户信息表

对应实体 org.activiti.engine.impl.persistence.entity.UserEntityImpl

+-------------+--------------+------+-----+---------+-------+
| Field       | Type         | Null | Key | Default | Extra |
+-------------+--------------+------+-----+---------+-------+
| ID_         | varchar(64)  | NO   | PRI | NULL    |       |
| REV_        | int(11)      | YES  |     | NULL    |       |
| FIRST_      | varchar(255) | YES  |     | NULL    |       |
| LAST_       | varchar(255) | YES  |     | NULL    |       |
| EMAIL_      | varchar(255) | YES  |     | NULL    |       |
| PWD_        | varchar(255) | YES  |     | NULL    |       |
| PICTURE_ID_ | varchar(64)  | YES  |     | NULL    |       |
+-------------+--------------+------+-----+---------+-------+

3.2. 用户扩展信息

对应实体 org.activiti.engine.impl.persistence.entity.IdentityInfoEntityImpl

+------------+--------------+------+-----+---------+-------+
| Field      | Type         | Null | Key | Default | Extra |
+------------+--------------+------+-----+---------+-------+
| ID_        | varchar(64)  | NO   | PRI | NULL    |       |
| REV_       | int(11)      | YES  |     | NULL    |       |
| USER_ID_   | varchar(64)  | YES  |     | NULL    |       |
| TYPE_      | varchar(64)  | YES  |     | NULL    |       |
| KEY_       | varchar(255) | YES  |     | NULL    |       |
| VALUE_     | varchar(255) | YES  |     | NULL    |       |
| PASSWORD_  | longblob     | YES  |     | NULL    |       |
| PARENT_ID_ | varchar(255) | YES  |     | NULL    |       |
+------------+--------------+------+-----+---------+-------+
  • USER_ID_: 关联用户 id
  • TYPE_: 类型(固定值)
  • KEY_: 属性名
  • VALUE_: 属性值
  • PASSWORD_: 密码(未使用)
  • PARENT_ID_: 上级关联(不建议使用)

3.3. ACT_ID_GROUP

对应实体 org.activiti.engine.impl.persistence.entity.GroupEntityImpl

+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| ID_   | varchar(64)  | NO   | PRI | NULL    |       |
| REV_  | int(11)      | YES  |     | NULL    |       |
| NAME_ | varchar(255) | YES  |     | NULL    |       |
| TYPE_ | varchar(255) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+

3.4. 用户组关系表

对应实体 org.activiti.engine.impl.persistence.entity.MembershipEntityImpl

+-----------+-------------+------+-----+---------+-------+
| Field     | Type        | Null | Key | Default | Extra |
+-----------+-------------+------+-----+---------+-------+
| USER_ID_  | varchar(64) | NO   | PRI | NULL    |       |
| GROUP_ID_ | varchar(64) | NO   | PRI | NULL    |       |
+-----------+-------------+------+-----+---------+-------+

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
public void testIdentity() {
IdentityService identityService = activitiRule.getIdentityService();
User user1 = identityService.newUser("user1");
user1.setFirstName("firstName");
user1.setLastName("lastName");
user1.setEmail("user1@126.com");
user1.setPassword("pwd");
identityService.saveUser(user1);
User user2 = identityService.newUser("user2");
identityService.saveUser(user2);
Group group1 = identityService.newGroup("group1");
group1.setName("for test");
identityService.saveGroup(group1);
identityService.createMembership(user1.getId(), group1.getId());
identityService.createMembership(user2.getId(), group1.getId());
// 扩展信息
identityService.setUserInfo(user1.getId(), "age", "18");
identityService.setUserInfo(user1.getId(), "identity", "destiny");
}

4. 运行时流程数据表

数据表分类 描述
ACT_RU_EXECUTION 流程实例与分支执行信息
ACT_RU_TASK 用户任务信息
ACT_RU_VARIABLE 变量信息
ACT_RU_IDENTITYLINK 参与者相关信息
ACT_RU_EVENT_SUBSCR 事件监听表
ACT_RU_JOB 作业表
ACT_RU_TIMER_JOB 定时器表
ACT_RU_SUSPENDED_JOB 暂停作业表
ACT_RU_DEADLETTER_JOB 死信表

4.1. ACT_RU_EXECUTION

对应实体类 org.activiti.engine.impl.persistence.entity.ExecutionEntityImpl

关键字段 描述
PROC_INST_ID_ 流程实例 ID
BUSINESS_KEY_ 业务标志
PARENT_ID_ 父执行信息
PROC_DEF_ID_ 流程定义 ID
SUPER_EXEC_ 父流程实例对应的执行
ACT_ID_ 流程定义节点 ID
IS_ACTIVE 是否活动的执行 0-非活动, 1-活动
IS_CONCURRENT_ 是否并行分支 0-非, 1-是
IS_SCOPE_ 是否全局流程执行 0-非, 1-是
IS_EVENT_SCOPE_ 是否激活状态
SUSPENSION_STATE 挂起状态 1-正常, 2-挂起
LOCK_TIME_ 锁定时间

4.2. ACT_RU_TASK

对应实体类 org.activiti.engine.impl.persistence.entity.TaskEntityImpl

关键字段 描述
EXECUTION_ID_ 执行流 id
PROC_INST_ID_ 流程实例 ID
PROC_DEF_ID_ 流程定义 ID
PARENT_TASK_ID_ 父任务
TASK_DEF_KEY_ 任务定义 ID
NAME_ 任务定义名称
OWNER_ 拥有人
ASSIGNEE_ 代理人
DELEGATION_ 委托状态 PENDING-委托中, RESOLVED 已处理
PRIORITY_ 优先级
DUE_DATE_ 过期时间
FORM_KEY_ 表单标志

4.3. ACT_RU_VARIABLE

对应实体类 org.activiti.engine.impl.persistence.entity.VariableInstanceEntityImpl

关键字段 描述
TYPE_ 变量名称(integer, string, double, json)
NAME_ 变量名
BYTEARRAY_ID_ 资源表 id
DOUBLE_ 浮点值
LONG_ 长整型数值
TEXT_ 文本值

对应实体类 org.activiti.engine.impl.persistence.entity.IdentityInfoEntityImpl

当用户和流程建立关系的时候, 就会在此表中插入记录

关键字段 描述
ID_ 主键
GROUP_ID_ 用户组 ID
TYPE_ 类型 assignee, candidate, owner, starter…
USER_ID_ 用户 ID
TASK_ID_ 任务 ID
PROC_INST_ID_ 流程实例

4.5. ACT_RU_EVENT_SUBSCR

对应实体类 org.activiti.engine.impl.persistence.entity.EventSubscriptionEntityImpl

关键字段 描述
EVENT_TYPE_ 事件类型 message, signal
EVENT_NAME_ 事件名称
EXECUTION_ID_ 流程执行 ID
PROC_INST_ID_ 流程实例 ID
ACTIVITY_ID_ 流程定义节点 ID
CONFIGURATION_ 配置

4.6. ACT_RU_JOB

对应实体类 org.activiti.engine.impl.persistence.entity.JobEntityImpl

关键字段 描述
TYPE_ 类型
LOCK_EXP_TIME_ 锁定过期时间
LOCK_OWNER_ 锁定接点
EXCLUSIVE_ 是否唯一
RETRIES_ 重试次数3
REPEAT_ 重复表达式 R5/PT10S
EXCEPTION_STACK_ID_ 异常堆栈(资源表 ID)
EXCEPTION_MSG_ 异常信息
DUEDATE_ 过期时间
HANDLER_TYPE_ 处理器类型
HANDLER_CFG 处理器配置
EXECUTION_ID_ 流程执行表 ID

4.7 测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
@Test
public void testRuntime() {
Deployment deployment = activitiRule.getRepositoryService()
.createDeployment()
.name("二次审批")
.addClasspathResource("org/destiny/activiti/SecondApprove.bpmn20.xml")
.deploy();
log.info("deployment: {}", deployment);
Map<String, Object> variables = Maps.newHashMap();
variables.put("k1", "v1");
ProcessInstance processInstance = activitiRule.getRuntimeService()
.startProcessInstanceByKey("SecondApprove", variables);
}

4.7.1 ACT_RU_EXECUTION 表

执行完成后, ACT_RU_EXECUTION 表会生成如下两条记录, 流程启动和用户任务

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
*************************** 1. row ***************************
ID_: 5
REV_: 1
PROC_INST_ID_: 5
BUSINESS_KEY_: NULL
PARENT_ID_: NULL
PROC_DEF_ID_: SecondApprove:1:4
SUPER_EXEC_: NULL
ROOT_PROC_INST_ID_: 5
ACT_ID_: NULL
IS_ACTIVE_: 1
IS_CONCURRENT_: 0
IS_SCOPE_: 1
IS_EVENT_SCOPE_: 0
IS_MI_ROOT_: 0
SUSPENSION_STATE_: 1
CACHED_ENT_STATE_: NULL
TENANT_ID_:
NAME_: NULL
START_TIME_: 2018-12-12 03:40:16.634
START_USER_ID_: NULL
LOCK_TIME_: NULL
IS_COUNT_ENABLED_: 0
EVT_SUBSCR_COUNT_: 0
TASK_COUNT_: 0
JOB_COUNT_: 0
TIMER_JOB_COUNT_: 0
SUSP_JOB_COUNT_: 0
DEADLETTER_JOB_COUNT_: 0
VAR_COUNT_: 0
ID_LINK_COUNT_: 0
*************************** 2. row ***************************
ID_: 7
REV_: 1
PROC_INST_ID_: 5
BUSINESS_KEY_: NULL
PARENT_ID_: 5
PROC_DEF_ID_: SecondApprove:1:4
SUPER_EXEC_: NULL
ROOT_PROC_INST_ID_: 5
ACT_ID_: submitApprove
IS_ACTIVE_: 1
IS_CONCURRENT_: 0
IS_SCOPE_: 0
IS_EVENT_SCOPE_: 0
IS_MI_ROOT_: 0
SUSPENSION_STATE_: 1
CACHED_ENT_STATE_: NULL
TENANT_ID_:
NAME_: NULL
START_TIME_: 2018-12-12 03:40:16.636
START_USER_ID_: NULL
LOCK_TIME_: NULL
IS_COUNT_ENABLED_: 0
EVT_SUBSCR_COUNT_: 0
TASK_COUNT_: 0
JOB_COUNT_: 0
TIMER_JOB_COUNT_: 0
SUSP_JOB_COUNT_: 0
DEADLETTER_JOB_COUNT_: 0
VAR_COUNT_: 0
ID_LINK_COUNT_: 0
  • 两条记录的 PROC_DEF_ID_ 相同, 说明是同一个流程的实例.
  • 第一条记录的 ID_ 是5, 第二条记录的 PARENT_ID_ 是 5, 说明第二条是第一条生成的.
  • 第二条记录的 ACT_ID_ 值为 submitApprove, 代表 userTask 的一个节点
  • 第二条记录的 IS_SCOPE 值为 0, 代表不是一个全局的执行流, 而第一条是一个全局执行流.

4.7.2 ACT_RU_TASK 表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
*************************** 1. row ***************************
ID_: 10
REV_: 1
EXECUTION_ID_: 7
PROC_INST_ID_: 5
PROC_DEF_ID_: SecondApprove:1:4
NAME_: 填写申请信息
PARENT_TASK_ID_: NULL
DESCRIPTION_: NULL
TASK_DEF_KEY_: submitApprove
OWNER_: NULL
ASSIGNEE_: NULL
DELEGATION_: NULL
PRIORITY_: 50
CREATE_TIME_: 2018-12-12 03:40:16.641
DUE_DATE_: NULL
CATEGORY_: NULL
SUSPENSION_STATE_: 1
TENANT_ID_:
FORM_KEY_: NULL
CLAIM_TIME_: NULL
  • PROC_DEF_ID_ 为 SecondApprove:1:4

4.7.3. ACT_RU_VARIABLE 表

保存启动时候设置的变量

1
2
3
4
5
6
7
8
9
10
11
12
13
*************************** 1. row ***************************
ID_: 6
REV_: 1
TYPE_: string
NAME_: k1
EXECUTION_ID_: 5
PROC_INST_ID_: 5
TASK_ID_: NULL
BYTEARRAY_ID_: NULL
DOUBLE_: NULL
LONG_: NULL
TEXT_: v1
TEXT2_: NULL

执行设置所属人的代码:

1
2
3
4
5
6
7
8
9
10
@Test
public void testSetOwner() {
TaskService taskService = activitiRule.getTaskService();
Task task = taskService
.createTaskQuery()
.processDefinitionKey("SecondApprove")
.singleResult();
// 设置所属人
taskService.setOwner(task.getId(), "destiny");
}
*************************** 1. row ***************************
          ID_: 2501
         REV_: 1
    GROUP_ID_: NULL
        TYPE_: participant
     USER_ID_: destiny
     TASK_ID_: NULL
PROC_INST_ID_: 5
 PROC_DEF_ID_: NULL
 

而此时在 ACT_RU_TASK 表, 对应的 task 的 OWNER_ 字段已经赋值为 destiny

4.7.5 ACT_RU_TASK

*************************** 1. row ***************************
              ID_: 10
             REV_: 2
    EXECUTION_ID_: 7
    PROC_INST_ID_: 5
     PROC_DEF_ID_: SecondApprove:1:4
            NAME_: 填写申请信息
  PARENT_TASK_ID_: NULL
     DESCRIPTION_: NULL
    TASK_DEF_KEY_: submitApprove
           OWNER_: destiny
        ASSIGNEE_: NULL
      DELEGATION_: NULL
        PRIORITY_: 50
     CREATE_TIME_: 2018-12-12 07:19:33.134
        DUE_DATE_: NULL
        CATEGORY_: NULL
SUSPENSION_STATE_: 1
       TENANT_ID_:
        FORM_KEY_: NULL
      CLAIM_TIME_: NULL
      

5. 历史流程数据表

数据表分类 描述
ACT_HI_PROCINST 历史流程实例表
ACT_HI_ACTINST 历史节点信息表, 执行过程中每经过一个节点就会插入一条记录
ACT_HI_TASKINST 历史任务表
ACT_HI_VARINST 历史变量
ACT_HI_IDENTITYLINK 历史参与者
ACT_HI_DETAIL 历史变更, 当使用 FormService 提交表单时, 表单的属性就会存储在该表, 以及变量的更改
ACT_HI_ATTACHMENT 附件
ACT_HI_COMMENT 评论
ACT_EVT_LOG 事件日志

5.1 ACT_HI_PROCINST

| 关键字段 |

>