zoukankan      html  css  js  c++  java
  • Acitiviti数据库表设计(学习笔记)

    ACT_ID_*:与权限,用户与用户组,以及用户与用户组关系相关的表

    ACT_RU_*:代表了流程引擎运行时的库表,RU表示Runtime

    ACT_HI_*:HI表示History当流程完成了节点以后,就将其迁移到历史数据库表


    ACT_GE_*(通用数据库 )涉及到两个表:

     

    act_ge_property:属性表,保存一些流程引擎的kv键值属性

    对应数据库实体:PropertyEntityImpl


    act_ge_bytearray:资源表,存储的是一些流程定义的资源信息(包括流程定义文件xml、流程定义的流程图,都被序列化成字节流存储在资源表里)

     对应数据库实体:ByteArrayEntityImpl

    定义有两种方式,可以用他的自动部署,也可以手动。

    public class DbConfigTest {
        private static final Logger LOGGER =  LoggerFactory.getLogger(configDBTest.class);
    
        @Rule
        public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
    
        @Test
        public void testDbConfig(){
                //自动
                activitiRule.getRepositoryService()
                        .createDeployment()
                        .name("指定部署名称")
                        .addClasspathResource("my-process.bpmn20.xml");
        }
    
        //手工添加act_ge_bytearray资源库信息
        @Test
        public void testbytearrayinsert(){
            //获取managementService,通过managementService去执行命令
            ManagementService managementService = activitiRule.getManagementService();
            Object o = managementService.executeCommand(new Command<Object>() {
    
                @Override
                public Object execute(CommandContext commandContext) {
                    ByteArrayEntity entity = new ByteArrayEntityImpl();
                    entity.setName("test");
                    entity.setBytes("test message".getBytes());
                    //根据上下文获取对象
                    commandContext.getByteArrayEntityManager().insert(entity);
    
                    return null;
                }
            });
    
        }
    }

    看数据库表效果:



    ACT_RE_*(流程定义存储表)设计到四张表:

     存储的都是些流程信息的名字等信息。


    ACT_ID_*(身份数据表)涉及到四个表:

    ACT_ID_USER对应实体UserEntityImpl

    ID_:对应登录的用户名

    REV_:版本信息

    FIRST_:firstname

    LAST_:lastname

    EMAIL_:email

    PWD_:password

    PICTURE_ID_:对应用户头像信息,即头像的url

    ACT_ID_INFO对应实体IdentityInfoEntityImpl

    TYPE_:类型,针对user的

    KEY_:属性名

    VALUE_;属性值

    如果要用key与value扩展,例如:key可以放age,value可以放18;

    PASSWORD_:密码(并没有使用到)

    PARENT_ID_:上级关联(这个字段表明了可以用ACT_ID_INFO做一些树状的关联)

    ACT_ID_GROUP对应实体GroupEntityImpl

     ID_:跟用户组关联的唯一键

    REV_:版本信息

    NAME_:对group的一个描述

    TYPE_:是自定义的类型,可以扩展一下业务信息

    ACT_ID_MEMBERSHIP对应实体MembershipEntityImpl

    USER_ID_:

    GROUP_ID_:

     这里主要是体现了一个简单的多对多关系。

     记录一下对这几个身份数据表插入数据的操作:

    public class DbIdentityTest {
        private static final Logger LOGGER =  LoggerFactory.getLogger(configDBTest.class);
    
        @Rule
        public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
    
        @Test
        public void testIdentity(){
            //对用户和用户组的操作要先获取对应的service
            IdentityService identityService = activitiRule.getIdentityService();
            //identityService或者identity数据可以去可选的设置,在这里面默认是设置关闭掉的,
            // 所以需要去流程定义文件里打开
            //          <!-- 打开用户相关的信息设置 -->
            //        <property name="dbIdentityUsed" value="true"/>
            //这样数据库就会自动生成有关用户信息的表
    
            //1.创建一个用户User,例:创建一个用户id为lll
            User lll = identityService.newUser("lll");
            //接着可以选择性的给用户设置一些属性信息
            lll.setFirstName("firstName");
            lll.setLastName("lastName");
            lll.setEmail("lxk@qq.com");
            lll.setPassword("pssword");
            //设置完这些用户信息,就可以对这个用户进行保存了
            identityService.saveUser(lll);
    
            //2.创建一个用户组Group,例:创建一个用户组id为BossGroup
            Group bossGroup1 = identityService.newGroup("BossGroup1");
            //同样可以选择性的给用户组设置一些属性信息
            bossGroup1.setName("Boss");
            //保存这个用户组
            identityService.saveGroup(bossGroup1);
    
            //3.接着就可以创建用户与组的关系了
            identityService.createMembership(lll.getId(),bossGroup1.getId());//createMembership这里面有两个参数,一个指定userId,一个是指定groupId
    
            //为了体现用户与用户组多对多的关系,可以再创建一个用户
            User lll2 = identityService.newUser("lll2");
            identityService.saveUser(lll2);
            //同样再把这个新增的用户添加进组
            identityService.createMembership(lll2.getId(),bossGroup1.getId());
            //至此操作的使用,一共涉及到三张表:act_id_user、act_id_group、act_id_membership
    
            //用户扩展信息表act_procdef_info的使用:(这里针对之前创建的lxk用户来使用扩展信息表,增加年龄与地址的信息)
            identityService.setUserInfo(lll.getId(),"age","18");//分别对应了表中USER_ID_:并联用户ID、KEY_:属性名、VALUE_;属性值  这三个字段
            identityService.setUserInfo(lll.getId(),"address","成都");
        }
    }

    执行完数据库效果如下:

    act_id_user :(这里id为主键)

    act_id_group :(这里id为主键)

    act_id_membership :

    act_id_info :(这里id自动给的)


    ACT_RU_*(运行时流程数据表)涉及到九个表:

    Task:当userTask执行到此处时,会在Task表里插入数据

    Variable:当启动流程、或者在流程过程中设置的一些变量信息,会存储在这张表

    Identitylink:跟参与者信息相关的表,当我们设置一个用户的owner或用户的代办人、候选人的时候,都会在该表写入信息

    event_subscr:流程中许多地方需要等待一个message或者singno,一个消息或者一个事件的情况下,这种监听的记录,都会存储在这张表里

    job在6.0版本以后重构了一下,以前只有一个jbo表,现在有四个。

    Job:一般作业表

    timer_job:定时器作业表

    suspended_job:当挂起的时候,暂停的作业会存放在这张表:

    deadletter_job:当一个作业重复了三四次都没有成功执行下去,就会将它挪入这张表,所以说这张表的里数据是需要管理人员去关注的,需要查明原因,为什么job没有执行成功

    ACT_ID_EXECUTUION对应实体ExecutionEntityImpl:

    PROC_INST_ID_:流程实例ID,对应流程实例的ID的外键

    BUSINESS_KEY_:业务标志

    PARENT_ID_:标识这个流程实例是由哪一个流程实例启动的(如果是直接的流程实例的启动,那么这列为null)

    PROC_DEF_ID_:流程定义ID  有时候会和流程执行ID是相同的

    SUPERT_EXEC_:父流程实例对应的执行

    ACT_ID_:流程定义节点ID  指流程定义里面执行到这个节点对应到流程定义这个节点的ID

    ACT_RU_EXECUTUION对应实体ExecutionEntityImpl:

    IS_ACTIVE_:是否活动的执行  0非活动,1活动

    IS_CONCURRENT_:是否并行分支   0非  1是

    IS_SCOPE_:是否全局流程执行 0非 1是

    IS_ECENT_SCOPE_:是否激活状态

    SUSPENSION_STATE:挂起状态 1正常 、2挂起

    LOCK_TIME_:锁定时间

    ACT_RU_TASK用户任务表对应的实体类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_:表单标志

    变量信息表

    ACT_RU_VARIABLE对应实体类VariableInstanceEntityImpl:

    TYPE_:变量类型(integer/string/double/json...)

    NAME_:变量名 对应扩展的属性的名称   如果变量非常大的话,就会将其存进二进制的资源表并在BYTEARRAY_ID_存入这张表的ID

    BYTEARRAY_ID_:资源表ID

    DOUBLE_:浮点值  如果变量是浮点型就存在这

    LONG_:长整型数值  如果变量是纯数字的,不管是integer还是long它都会存在这个字段下

    TEXT_:文本值   如果是一个普通的文本,且它的长度没有超过一点的限制,它就会作为文本字符串存在这个字段下面

    参与者信息表:当一个用户与一个流程建立关系的时候,就会在这张表里插入一条记录

    比如在使用RuntimeService设置一个流程实例的owner或者signal时,都会在这张表里插入一条记录。

    ACT_RU_IDENTITYLINK对应实体类IdentityLinkEntityImpl

    ID_:主键

    GROUP_ID_:用户组ID

    TYPE_:类型assignee,candidate,owner,starter

    USER_ID_:用户ID

    TASK_ID_:任务ID

    PROC_INST_ID_:流程实例

    事件订阅信息表

    ACT_RU_EVENT_SUBSCR对应实体类EventSubscriptionEntityImpl

    EVENT_TYPE_:事件类型message,signal  消息、信号

    EVENT_NAME_:事件名称   (事件一般都跟流程执行有一定关系)

    EXECUTION_ID_:流程执行ID

    PROC_INST_ID_:流程实例ID

    ACTIVITY_ID_:流程定义节点ID(标识事件触发对应的流程定义节点)

    CONFIGURATION_:配置(可以对流程事件做一些对应的特殊配置信息存储起来)

    作业信息表:

    ACT_RU_JOB对应实体类 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

    记录一下对这几个表的操作:

    启动一个流程会操作的表

    public class DbRuntimeTest {
        private static final Logger LOGGER =  LoggerFactory.getLogger(configDBTest.class);
    
        @Rule
        public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
    
        @Test
        public void testRuntime(){
                activitiRule.getRepositoryService()
                        .createDeployment()
                        .name("指定部署名称2")
                        .addClasspathResource("second_approve.bpmn20.xml")
                        .deploy();
    
            Map<String, Object> variables = Maps.newHashMap();
            variables.put("key1","value1");
    
            //启动流程,且在启动时,传入一些变量 值variables
            activitiRule.getRuntimeService()
                        .startProcessInstanceByKey("erjishenpiliucheng",variables);
        }
    }

    会操作到的表有:

    1.

     以及表

    2.

     执行到这里遇到了userTask,需要指定它去提交一个表单,所以到这里就暂停了,并且userTask里面会有一条记录。

    因为前面在启动时插入了一些变量,所以变量表里面也存在一条记录

    3.

     上面启动一个流程的java代码里面的操作,会影响到数据表有这几个

    接着记录一下给其他几个表插入数据需要如何操作:

    接着上面流程暂停的步骤继续操作,指定一个owner,来让流程继续下去

     @Test //给参与者赋值
        public void testSetOwner(){
            TaskService taskService =  activitiRule.getTaskService();
            //指定流程定义key,这里因为流程遇到了userTask会暂停,
            // 在task表里会记录是停在了哪个步骤的任务,所以
            // 需要查出task来给他指定一个owner来将流程继续下去
            Task task = taskService.createTaskQuery().processDefinitionKey("erjishenpiliucheng").singleResult();
            //使用taskService设置owner
            taskService.setOwner(task.getId(),"lxk");
        }

    受影响的数据库表:

    1.

    这里可以看到这张表记录到,lxk以参与者的类型参与到了流程id  52505 的这个流程中,具体这个参与者在流程中参与了什么,有什么职责,要刷新一下task表

    会发现OWNER_中同时指定了lxk这个用户。

    如何让事件订阅信息表有数据呢?那就必须要让流程定义支持事件订阅,也就是说它必须支持message或者signal事件,接下来修改流程定义文件

    使用my-process-message.bpmn20.xml ,代码如下
    <?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">
    
      <message id="messageStart" name="my-message"></message>
      <process id="my-process">
    
        <startEvent id="start">
          <messageEventDefinition messageRef="messageStart"/>
        </startEvent>
    
        <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask"/>
        <userTask id="someTask" name="Activiti is awesome!"/>
        <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end"/>
    
        <endEvent id="end"/>
    
      </process>
    
    </definitions>

    然后部署一下流程定义文件:

    public void testMyssage(){
            activitiRule.getRepositoryService()
                    .createDeployment()
                    .addClasspathResource("my-process-message.bpmn20.xml")
                    .deploy();
        }

    执行一下,会发现表:

    中就有数据了:

    这里EXECUTION_ID_ 与 PROC_INST_ID_为null,涉及到两种流程定义文件的区别:

    一种是前者,刚才修改的那个定义文件,它的消息时间实在开始节点的位置,它可以接收一个消息 驱动流程的启动

     而另一种是只有在流程开始以后,在流程的一个节点上去监听messageStart的消息,定义文件具体内容如下:

    <?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">
    
      <message id="messageStart" name="my-message"></message>
      <process id="my-process">
    
        <startEvent id="start"/>
    
        <sequenceFlow id="flow1" sourceRef="start" targetRef="message-received"/>
        <intermediateCatchEvent id="message-received">
        <messageEventDefinition messageRef="messageStart"/>
        </intermediateCatchEvent>
        <sequenceFlow id="flow2" sourceRef="message-received" targetRef="end"/>
    
        <endEvent id="end"/>
    
      </process>
    
    </definitions>

    部署以后,需要再启动流程才可以看见EXECUTION_ID_ 与 PROC_INST_ID_插入数据。

    接着是job表:

    需要在流程定义文件中定一个 定时任务:

    <?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: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="my-process">
    
            <!--这种是自行启动流程的方式<startEvent id="start" />-->
            <!--定时任务来启动流程-->
            <startEvent id="start">
                <timerEventDefinition>
                    <!-- 共执行5次,间隔为10S -->
                    <timeCycle>R5/PT10S</timeCycle>
                </timerEventDefinition>
            </startEvent>
            <sequenceFlow id="flow1" sourceRef="start" targetRef="someTask" />
            
            <userTask id="someTask" name="Activiti is awesome!" />
            <sequenceFlow id="flow2" sourceRef="someTask" targetRef="end" />
    
            <endEvent id="end" />
    
        </process>
    
    </definitions>

    启动流程:

        public void testJob() throws InterruptedException {
            activitiRule.getRepositoryService()
                    .createDeployment()
                    .addClasspathResource("my-process_job.bpmn20.xml")
                    .deploy();
    
            Thread.sleep(1000*30L);
        }

    观察数据库 

      插入了数据:



    ACT_HI_*(历史流程数据表)涉及到九个表:

    事件日志表比较特殊,只能插入与删除,无法修改

    这里面有几个单表:

    主要是跟TASK相关的

    附件表与评论表:

    ACT_HI_ATTACHMENT:在用户任务的处理过程中,可以提交一些附件

    ACT_HI_COMMENT:或者添加一些评论

    一般都是有需求时,对它们单独进行编辑,这两个表没有对应的运行时表,因为在运行的操作的过程中,提交的内容直接就把它作为历史记录存储起来

    ACT_HI_PROCINST对应的实体类HistoricProcessInstanceEntityImpl

    PROC_INST_ID_:流程实例ID

    BUSINESS_KEY_:业务ID

    PROC_DEF_ID_:流程定义ID

    START_TIME_:开始时间

    END_TIME_:结束时间

    DURATION_:执行时长

    START_USER_ID_:流程发起人

    START_ACT_ID_:开始节点ID

    END_ACT_ID_:结束节点ID

    SUPER_PROCESS_INSTANCE_ID_:父流程实例

    DELETE_REASON_:删除原因

    TENANT_ID_:多租户

    记录一下操作实例:

    public class DbHistoryTest {
        private static final Logger LOGGER =  LoggerFactory.getLogger(configDBTest.class);
    
        @Rule
        public ActivitiRule activitiRule = new ActivitiRule("activiti_druid.cfg.xml");//传入自定义的mdc配置文件
    
        @Test
        public void testHistory(){
                //自动
                activitiRule.getRepositoryService()
                        .createDeployment()
                        .name("指定部署名称")
                        .addClasspathResource("my-process.bpmn20.xml");
    
            RuntimeService runtimeService = activitiRule.getRuntimeService();
    
            Map<String, Object> variables = Maps.newHashMap();
            variables.put("key0","value0");
            variables.put("key1","value1");
            variables.put("key2","value2");
    
            ProcessInstance processInstance = runtimeService.startProcessInstanceByKey("my-process", variables);
            //启动完以后获取流程实例ID,修改变量
            runtimeService.setVariable(processInstance.getId(),"key1","value1");
    
            //获取TaskService,然后获取到当前唯一需要执行的task
            TaskService taskService = activitiRule.getTaskService();
    
            //获取task是要演示一下参与者里面是否有添加一条记录
            Task task = taskService.createTaskQuery().processInstanceId(processInstance.getId()).singleResult();
    
            //给当前task指定一个owner
            taskService.setOwner(task.getId(),"lxk");
            //同时上传一些附件
            taskService.createAttachment("url",task.getId(),processInstance.getId(),"附件","附件描述","/url/test.png");
            //同时再添加一些评论
            taskService.addComment(task.getId(),task.getProcessInstanceId(),"评论1");
            taskService.addComment(task.getId(),task.getProcessInstanceId(),"评论2");
    
            //完成这些操作以后,可以通过formService来将表单提交上去,也可以用taskservice来提交
            Map<String, String> properties = Maps.newHashMap();
            properties.put("key2","value2_1覆盖");
            properties.put("key3","value3_1");
            activitiRule.getFormService().submitTaskFormData(task.getId(),properties);
        }
    }

    执行效果:

    表:

    表:

    表:

    表:

      附件表:

    评论表:

  • 相关阅读:
    to_char &&to_date
    java中Integer 与 String 类型的 相互 转换
    group by 的用法
    谈 计算时间的天数差
    领域建模
    Java Classloader详解
    阿里巴巴Java招聘
    Maven Archetype
    负载均衡
    Maven
  • 原文地址:https://www.cnblogs.com/xk920/p/10770048.html
Copyright © 2011-2022 走看看