zoukankan      html  css  js  c++  java
  • 01-activiti6基础——引擎如何数据库操作及相关表

    官网文档:https://www.activiti.org/userguide/#queryAPI

    1. Activit的简单源码解读

         activiti的官方文档讲解详细很详细,也很范。按着文档写完了一个简单的demo发现,现实中的大多数问题,还是没法很好的解决。

    例如:首先我需要知道的是,activiti的有那些表,及各个表的作用。这个网上有人罗列过,但总是觉得不通透。

    所以,我先简单看了一下activiti数据处理的源码。

    1.1 流程发布

    • RepositoryServiceImpl

    进行对那个操作的封装,传递Command接口的对应子类,里面封装了具体的操作

      public Deployment deploy(DeploymentBuilderImpl deploymentBuilder) {
        return commandExecutor.execute(new DeployCmd<Deployment>(deploymentBuilder));
      }
    
    • CommandInvoker

    commandExecutor.execute() 这个方法的执行本质,是里面的CommandInterceptor执行链式的execute,而实质执行的是传进来的CMD接口类的execute方法。具体如下所示。

     public <T> T execute(final CommandConfig config, final Command<T> command) {
        final CommandContext commandContext = Context.getCommandContext();
    
        //省略一些代码
    
        commandContext.getAgenda().planOperation(new Runnable() {
          @Override
          public void run() {
            commandContext.setResult(command.execute(commandContext));//这里是关键
          }
        });
    
         // 省略一些代码。。。。。。。。。。。。
    
        return (T) commandContext.getResult();
      }
    
    
    • DeployCmd(从这里调用DataManager的实现类进行相关数据库操作)
    public Deployment execute(CommandContext commandContext) {
    
        // Backwards compatibility with Activiti v5
        if (commandContext.getProcessEngineConfiguration().isActiviti5CompatibilityEnabled()
            && deploymentBuilder.getDeploymentProperties() != null 
            && deploymentBuilder.getDeploymentProperties().containsKey(DeploymentProperties.DEPLOY_AS_ACTIVITI5_PROCESS_DEFINITION)
            && deploymentBuilder.getDeploymentProperties().get(DeploymentProperties.DEPLOY_AS_ACTIVITI5_PROCESS_DEFINITION).equals(Boolean.TRUE)) {
          
            return deployAsActiviti5ProcessDefinition(commandContext);
        }
    
        return executeDeploy(commandContext);
      }
    
    
    
    • DeploymentEntityManagerImpl

    实际数据库操作的是DataManager的实现类,进行数据库操作。

    这个我们能看出来是有两个

    
     @Override
      public void insert(DeploymentEntity deployment) {
        insert(deployment, false);
    
        for (ResourceEntity resource : deployment.getResources().values()) {
          resource.setDeploymentId(deployment.getId());
          getResourceEntityManager().insert(resource);
        }
      }
    
    • 对应的xml操作

    在mapping目录下可以查找到对应的操作。前面的${prefix}标识数据库,activiti已经帮我们判断好了,不需要我们再传入。

      <insert id="insertDeployment" parameterType="org.activiti.engine.impl.persistence.entity.DeploymentEntityImpl">
        insert into ${prefix}ACT_RE_DEPLOYMENT(ID_, NAME_, CATEGORY_, KEY_, TENANT_ID_, DEPLOY_TIME_, ENGINE_VERSION_)
        values(#{id, jdbcType=VARCHAR}, #{name, jdbcType=VARCHAR}, #{category, jdbcType=VARCHAR}, #{key, jdbcType=VARCHAR}, #{tenantId, jdbcType=VARCHAR}, #{deploymentTime, jdbcType=TIMESTAMP}, #{engineVersion, jdbcType=VARCHAR})
      </insert>
    
    <insert id="insertResource" parameterType="org.activiti.engine.impl.persistence.entity.ResourceEntityImpl">
        insert into ${prefix}ACT_GE_BYTEARRAY(ID_, REV_, NAME_, BYTES_, DEPLOYMENT_ID_, GENERATED_)
        values (#{id, jdbcType=VARCHAR}, 1, #{name, jdbcType=VARCHAR}, #{bytes, jdbcType=${blobType}}, #{deploymentId, jdbcType=VARCHAR}, #{generated, jdbcType=BOOLEAN})  
      </insert>
    
    
    

    1.2 数据查询

    • DataManager

    数据查询操作本质都是通过DataManger的实现类MybatisDeploymentDataManager进行操作;

      @Override
      public List<Deployment> executeList(CommandContext commandContext, Page page) {
        checkQueryOk();
        return commandContext.getDeploymentEntityManager().findDeploymentsByQueryCriteria(this, page);
      }
    
      @Override
      @SuppressWarnings("unchecked")
      public List<Deployment> findDeploymentsByQueryCriteria(DeploymentQueryImpl deploymentQuery, Page page) {
        final String query = "selectDeploymentsByQueryCriteria";
        return getDbSqlSession().selectList(query, deploymentQuery, page);
      }    
    
    • 查找xml中对应的sql
      <select id="selectDeploymentsByQueryCriteria" parameterType="org.activiti.engine.impl.DeploymentQueryImpl" resultMap="deploymentResultMap">
      	${limitBefore}
        select distinct RES.* ${limitBetween}
        <include refid="selectDeploymentsByQueryCriteriaSql"/>
        ${orderBy}
        ${limitAfter}
      </select>
    
    

    1.3 任务执行

    需要了解任务类型,以及网关相关知识。

    • TaskService
    taskService.complete(task.getId(), taskVariables);
    
    • AbstractCompleteTaskCmd
    protected void executeTaskComplete(CommandContext commandContext, TaskEntity taskEntity, Map<String, Object> variables, boolean localScope) {
        // Task complete logic
    
        if (taskEntity.getDelegationState() != null && taskEntity.getDelegationState().equals(DelegationState.PENDING)) {
          throw new ActivitiException("A delegated task cannot be completed, but should be resolved instead.");
        }
        //执行节点监听事件  
        commandContext.getProcessEngineConfiguration().getListenerNotificationHelper().executeTaskListeners(taskEntity, TaskListener.EVENTNAME_COMPLETE);
        if (Authentication.getAuthenticatedUserId() != null && taskEntity.getProcessInstanceId() != null) {
           //查找任务select * from ${prefix}ACT_RU_EXECUTION
           // where ROOT_PROC_INST_ID_ = (select ROOT_PROC_INST_ID_ from ${prefix}ACT_RU_EXECUTION where ID_ = #{parameter})
          ExecutionEntity processInstanceEntity = commandContext.getExecutionEntityManager().findById(taskEntity.getProcessInstanceId());
          //任务和identity绑定
          commandContext.getIdentityLinkEntityManager().involveUser(processInstanceEntity, Authentication.getAuthenticatedUserId(),IdentityLinkType.PARTICIPANT);
        }
    
        ActivitiEventDispatcher eventDispatcher = Context.getProcessEngineConfiguration().getEventDispatcher();
        if (eventDispatcher.isEnabled()) {
          if (variables != null) {
            eventDispatcher.dispatchEvent(ActivitiEventBuilder.createEntityWithVariablesEvent(ActivitiEventType.TASK_COMPLETED, taskEntity, variables, localScope));
          } else {
            eventDispatcher.dispatchEvent(ActivitiEventBuilder.createEntityEvent(ActivitiEventType.TASK_COMPLETED, taskEntity));
          }
        }
          //删除已有的任务相关数据
        commandContext.getTaskEntityManager().deleteTask(taskEntity, null, false, false);
    
        // Continue process (if not a standalone task) 激活下个步骤工作
        if (taskEntity.getExecutionId() != null) {
          ExecutionEntity executionEntity = commandContext.getExecutionEntityManager().findById(taskEntity.getExecutionId());
          Context.getAgenda().planTriggerExecutionOperation(executionEntity);
        }
      }
    
    

    1.4 获取类对应表名称

    ManagementService

      managementService.getTableName()
    

    TableDataManagerImpl

    static {
        // runtime
        entityToTableNameMap.put(TaskEntity.class, "ACT_RU_TASK");
        entityToTableNameMap.put(ExecutionEntity.class, "ACT_RU_EXECUTION");
        entityToTableNameMap.put(IdentityLinkEntity.class, "ACT_RU_IDENTITYLINK");
        entityToTableNameMap.put(VariableInstanceEntity.class, "ACT_RU_VARIABLE");
    
        entityToTableNameMap.put(JobEntity.class, "ACT_RU_JOB");
        entityToTableNameMap.put(TimerJobEntity.class, "ACT_RU_TIMER_JOB");
        entityToTableNameMap.put(SuspendedJobEntity.class, "ACT_RU_SUSPENDED_JOB");
        entityToTableNameMap.put(DeadLetterJobEntity.class, "ACT_RU_DEADLETTER_JOB");
        
    
        entityToTableNameMap.put(EventSubscriptionEntity.class, "ACT_RU_EVENT_SUBSCR");
        entityToTableNameMap.put(CompensateEventSubscriptionEntity.class, "ACT_RU_EVENT_SUBSCR");
        entityToTableNameMap.put(MessageEventSubscriptionEntity.class, "ACT_RU_EVENT_SUBSCR");
        entityToTableNameMap.put(SignalEventSubscriptionEntity.class, "ACT_RU_EVENT_SUBSCR");
    
        // repository
        entityToTableNameMap.put(DeploymentEntity.class, "ACT_RE_DEPLOYMENT");
        entityToTableNameMap.put(ProcessDefinitionEntity.class, "ACT_RE_PROCDEF");
        entityToTableNameMap.put(ModelEntity.class, "ACT_RE_MODEL");
        entityToTableNameMap.put(ProcessDefinitionInfoEntity.class, "ACT_PROCDEF_INFO");
    
        // history
        entityToTableNameMap.put(CommentEntity.class, "ACT_HI_COMMENT");
    
        entityToTableNameMap.put(HistoricActivityInstanceEntity.class, "ACT_HI_ACTINST");
        entityToTableNameMap.put(AttachmentEntity.class, "ACT_HI_ATTACHMENT");
        entityToTableNameMap.put(HistoricProcessInstanceEntity.class, "ACT_HI_PROCINST");
        entityToTableNameMap.put(HistoricVariableInstanceEntity.class, "ACT_HI_VARINST");
        entityToTableNameMap.put(HistoricTaskInstanceEntity.class, "ACT_HI_TASKINST");
        entityToTableNameMap.put(HistoricIdentityLinkEntity.class, "ACT_HI_IDENTITYLINK");
    
        // a couple of stuff goes to the same table
        entityToTableNameMap.put(HistoricDetailAssignmentEntity.class, "ACT_HI_DETAIL");
        entityToTableNameMap.put(HistoricDetailTransitionInstanceEntity.class, "ACT_HI_DETAIL");
        entityToTableNameMap.put(HistoricFormPropertyEntity.class, "ACT_HI_DETAIL");
        entityToTableNameMap.put(HistoricDetailVariableInstanceUpdateEntity.class, "ACT_HI_DETAIL");
        entityToTableNameMap.put(HistoricDetailEntity.class, "ACT_HI_DETAIL");
    
        // Identity module
        entityToTableNameMap.put(GroupEntity.class, "ACT_ID_GROUP");
        entityToTableNameMap.put(MembershipEntity.class, "ACT_ID_MEMBERSHIP");
        entityToTableNameMap.put(UserEntity.class, "ACT_ID_USER");
        entityToTableNameMap.put(IdentityInfoEntity.class, "ACT_ID_INFO");
    
        // general
        entityToTableNameMap.put(PropertyEntity.class, "ACT_GE_PROPERTY");
        entityToTableNameMap.put(ByteArrayEntity.class, "ACT_GE_BYTEARRAY");
        entityToTableNameMap.put(ResourceEntity.class, "ACT_GE_BYTEARRAY");
        
        entityToTableNameMap.put(EventLogEntryEntity.class, "ACT_EVT_LOG");
    
        // and now the map for the API types (does not cover all cases)
        apiTypeToTableNameMap.put(Task.class, "ACT_RU_TASK");
        apiTypeToTableNameMap.put(Execution.class, "ACT_RU_EXECUTION");
        apiTypeToTableNameMap.put(ProcessInstance.class, "ACT_RU_EXECUTION");
        apiTypeToTableNameMap.put(ProcessDefinition.class, "ACT_RE_PROCDEF");
        apiTypeToTableNameMap.put(Deployment.class, "ACT_RE_DEPLOYMENT");
        apiTypeToTableNameMap.put(Job.class, "ACT_RU_JOB");
        apiTypeToTableNameMap.put(Model.class, "ACT_RE_MODEL");
    
        // history
        apiTypeToTableNameMap.put(HistoricProcessInstance.class, "ACT_HI_PROCINST");
        apiTypeToTableNameMap.put(HistoricActivityInstance.class, "ACT_HI_ACTINST");
        apiTypeToTableNameMap.put(HistoricDetail.class, "ACT_HI_DETAIL");
        apiTypeToTableNameMap.put(HistoricVariableUpdate.class, "ACT_HI_DETAIL");
        apiTypeToTableNameMap.put(HistoricFormProperty.class, "ACT_HI_DETAIL");
        apiTypeToTableNameMap.put(HistoricTaskInstance.class, "ACT_HI_TASKINST");
        apiTypeToTableNameMap.put(HistoricVariableInstance.class, "ACT_HI_VARINST");
    
        // identity
        apiTypeToTableNameMap.put(Group.class, "ACT_ID_GROUP");
        apiTypeToTableNameMap.put(User.class, "ACT_ID_USER");
    
        // TODO: Identity skipped for the moment as no SQL injection is provided
        // here
      }
    
    

    以Task接口为例

    可以看到接口的实现类对应xml的命名空间

    2.activiti表格及对应的数据

    官方文档中的说明

    Activiti的数据库名称都以ACT_开头。第二部分是表用例的两个字符的标识。该用例也将与服务API大致匹配。
    
    ACT_RE_ *:RE代表repository。具有此前缀的表包含静态信息,例如流程定义和流程资源(图像,规则等)。
    
    ACT_RU_ *:RU代表runtime。这些是运行时表,其中包含流程实例,用户任务,变量,作业等的运行时数据。Activiti仅在流程实例执行期间存储运行时数据,并在流程实例结束时删除记录。这样可以使运行时表较小而又快速。
    
    ACT_ID_ *:ID代表identity。这些表包含身份信息,例如用户,组等。
    
    ACT_HI_ *:HI代表history。这些表包含历史数据,例如过去的流程实例,变量,任务等。
    
    ACT_GE_ *:general数据,用于各种用例中
    

    初次使用中使用到的表格(后续继续补充)

    类型 表格名称 存储的数据 备注
    生成 ACT_GE_BYTEARRAY 存储部署的bpmn相关文件
    re ACT_RE_DEPLOYMENT 发布的流程数据
    re act_re_procdef 存储流程分解数据
    runtime ACT_RU_TASK 正在运行的任务
    runtime ACT_RU_VARIABLE 用于存储流程流转中的字段 PROC_INST_ID_ 对应ACT_RU_TASK中的EXECUTION_ID_
    TASK_ID_ 对应 ACT_RU_TASK中的ID_
    runtime ACT_RU_EXECUTION 运行时流程执行实例
    history act_hi_taskinst 流程历史步骤数据
    history act_hi_variable 历史步骤流程中转字段
    history act_hi_procinst 已经发起的流程实例 已经结束的流程任务END_ACT_ID_不为空
  • 相关阅读:
    行转列函数listagg() WITHIN GROUP ()
    位图索引
    windows 杀掉进程
    vue 实践(过滤器)
    vue 总结
    vue v-show v-if 的使用
    vue v-for 绑定数据
    vue v-model实现数据的双向绑定
    vue .stop .self .capture .prevent 阻止冒泡
    vue v-on v-text 的运用
  • 原文地址:https://www.cnblogs.com/perferect/p/13234784.html
Copyright © 2011-2022 走看看