下面本人介绍一些activiti这款开源流程设计引擎的数据库表结构,首先阐述:我们刚开始接触或者使用一个新的东西(技术)时我们首先多问一下自己几个为什么?为什么activiti在工作流程领域这么流行呢?仅仅是因为开源么?实现如此强大的流程引擎,activiti底层设计是如何进行的?activiti中依赖哪些技术等?这些可能应该是那些刚接触这个开源流程引擎产品的人应该有的疑问。我们在用开源产品的都是其实应该多问自己为什么?这样才能有所进步,不是么?兴许你一时兴起,“起笔”就把一款属于你自己的开源作品给做出来了!
了解一个开源作品,它的底层很重要。在使用它之前,你是否尝试过了解它的底层。那么这些尝试是否对你有必要呢?个人解决有必要,首先这个东西确实在你看来是个有用的东西,你对它感兴趣。兴许将来你在应用它的时候可能会发现它的BUG,其实大牛写的东西也未必是完美的,兴许你在使用时候就发现其中不满意的东西,那么你就可以向开元社区提交的你的BUG!就比如说我们在了解activiti的底层数据结构之后,在我们使用activiti的时候发现一些数据查询过程中出现性能瓶颈时,我们可以尝试分析activiti的数据查询规则,activiti的数据访问层依赖于mybatis,那么我可以分析打包在jar包里的关于mybatis的sql配置部分,看看那些所谓大牛们写的sql是否存在问题。当你发现问题时,你可以对它进行修改,然后重新打包。从而满足自己在项目有中的需要。这些都是一些关于进阶了解一个开源作品的方式。在这样过程中你会发现你在某方面会有所进步。以上内容抛砖引玉,希望对你有所帮助!
好吧,请允许我废话了这么久,下面开始解析activiti的数据库底层的模型截图:
以上就activiti底层数据库23张表结构,个人觉得了解底层数据库模型是有必要的,让我们直观的了解一个开源作品的底层设计结构,对日后大伙使用的时候能有很大的帮助,特别是activiti的高级应用。大致看一下这些模型你们就知道activiti的23张表直接约束关系了!那么大家在使用activiti提供的servcies API查询activiti流程控制数据时就更清晰一些了!比如如下说明:
1)activiti的历史任务是单独的表来储存,表之间没有任何外间关联,从以上模型就可以看出
1、ACT_HI_ACTINST 流程活动历史记录信息
2、ACT_HI_ATTACHMENT
3、ACT_HI_COMMENT 流程评论信息
4、ACT_HI_DETAIL 流程明细信息
5、ACT_HI_IDENTITYLINK 流程身份关系信息
6、ACT_HI_PROCINST 流程历史信息
7、ACT_HI_TASKINST 任务历史信息
8、ACT_HI_VARINST 历史流程中的参数
2)historyService可查询历史数据表(可查询以上这些表,与流程历史相关数据的查询都可以通过historyService来查询)
1、historyService.createHistoricActivityInstanceQuery(); //查询ACT_HI_ACTINST表
2、historyService.createHistoricDetailQuery(); //查询ACT_HI_DETAIL表
3、historyService.createHistoricProcessInstanceQuery(); //查询ACT_HI_PROCINST表
4、historyService.createHistoricTaskInstanceQuery(); //查询ACT_HI_TASKINST表
5、historyService.createHistoricVariableInstanceQuery(); //查询ACT_HI_VARINST表
activiti其中数据的查询和判断都是类似的!在这里就不过多介绍了。
下面是actviti中mybatis的映射配置:
下面是就那其中一个映射配置来说明,如HistoricProcessInstance.xml:
insert into ${prefix}ACT_HI_TASKINST (
ID_,
PROC_DEF_ID_,
PROC_INST_ID_,
EXECUTION_ID_,
NAME_,
PARENT_TASK_ID_,
DESCRIPTION_,
OWNER_,
ASSIGNEE_,
START_TIME_,
CLAIM_TIME_,
END_TIME_,
DURATION_,
DELETE_REASON_,
TASK_DEF_KEY_,
FORM_KEY_,
PRIORITY_,
DUE_DATE_,
CATEGORY_,
TENANT_ID_
) values (
#{id ,jdbcType=VARCHAR},
#{processDefinitionId, jdbcType=VARCHAR},
#{processInstanceId, jdbcType=VARCHAR},
#{executionId, jdbcType=VARCHAR},
#{name ,jdbcType=VARCHAR},
#{parentTaskId ,jdbcType=VARCHAR},
#{description ,jdbcType=VARCHAR},
#{owner ,jdbcType=VARCHAR},
#{assignee ,jdbcType=VARCHAR},
#{startTime, jdbcType=TIMESTAMP},
#{claimTime, jdbcType=TIMESTAMP},
#{endTime, jdbcType=TIMESTAMP},
#{durationInMillis ,jdbcType=BIGINT},
#{deleteReason ,jdbcType=VARCHAR},
#{taskDefinitionKey ,jdbcType=VARCHAR},
#{formKey ,jdbcType=VARCHAR},
#{priority, jdbcType=INTEGER},
#{dueDate, jdbcType=TIMESTAMP},
#{category, jdbcType=VARCHAR},
#{tenantId, jdbcType=VARCHAR}
)
update ${prefix}ACT_HI_TASKINST set
EXECUTION_ID_ = #{executionId, jdbcType=VARCHAR},
NAME_ = #{name, jdbcType=VARCHAR},
PARENT_TASK_ID_ = #{parentTaskId, jdbcType=VARCHAR},
DESCRIPTION_ = #{description, jdbcType=VARCHAR},
OWNER_ = #{owner, jdbcType=VARCHAR},
ASSIGNEE_ = #{assignee, jdbcType=VARCHAR},
CLAIM_TIME_ = #{claimTime, jdbcType=TIMESTAMP},
END_TIME_ = #{endTime, jdbcType=TIMESTAMP},
DURATION_ = #{durationInMillis ,jdbcType=BIGINT},
DELETE_REASON_ = #{deleteReason ,jdbcType=VARCHAR},
TASK_DEF_KEY_ = #{taskDefinitionKey ,jdbcType=VARCHAR},
FORM_KEY_ = #{formKey ,jdbcType=VARCHAR},
PRIORITY_ = #{priority, jdbcType=INTEGER},
DUE_DATE_ = #{dueDate, jdbcType=TIMESTAMP},
CATEGORY_ = #{category, jdbcType=VARCHAR}
where ID_ = #{id}
delete from ${prefix}ACT_HI_TASKINST where ID_ = #{id}
from ${prefix}ACT_HI_TASKINST RES
from ${prefix}ACT_HI_TASKINST RES
left outer join ${prefix}ACT_HI_VARINST VAR ON RES.ID_ = VAR.TASK_ID_ or RES.PROC_INST_ID_ = VAR.EXECUTION_ID_
left outer join ${prefix}ACT_HI_VARINST VAR ON RES.ID_ = VAR.TASK_ID_
left outer join ${prefix}ACT_HI_VARINST VAR ON RES.PROC_INST_ID_ = VAR.EXECUTION_ID_ and VAR.TASK_ID_ is null
inner join ${prefix}ACT_HI_IDENTITYLINK HI on HI.TASK_ID_ = RES.ID_
inner join ${prefix}ACT_HI_PROCINST HPI ON RES.PROC_INST_ID_ = HPI.ID_
inner join ${prefix}ACT_RE_PROCDEF D on RES.PROC_DEF_ID_ = D.ID_
inner join ${prefix}ACT_HI_VARINST A${index} on RES.ID_ = A${index}.TASK_ID_
inner join ${prefix}ACT_HI_VARINST A${index} on RES.PROC_INST_ID_ = A${index}.PROC_INST_ID_
RES.ID_ = #{taskId}
and RES.PROC_DEF_ID_ = #{processDefinitionId}
and D.KEY_ = #{processDefinitionKey}
and D.KEY_ like #{processDefinitionKeyLike}
and D.NAME_ = #{processDefinitionName}
and D.NAME_ like #{processDefinitionNameLike}
and RES.PROC_INST_ID_ = #{processInstanceId}
and HPI.BUSINESS_KEY_ = #{processInstanceBusinessKey}
and HPI.BUSINESS_KEY_ like #{processInstanceBusinessKeyLike}
and RES.TASK_DEF_KEY_ = #{taskDefinitionKey}
and RES.TASK_DEF_KEY_ like #{taskDefinitionKeyLike}
and RES.EXECUTION_ID_ = #{executionId}
and RES.NAME_ = #{taskName}
and RES.NAME_ like #{taskNameLike}
and RES.PARENT_TASK_ID_ = #{taskParentTaskId}
and RES.DESCRIPTION_ = #{taskDescription}
and RES.DESCRIPTION_ like #{taskDescriptionLike}
and RES.DELETE_REASON_ = #{taskDeleteReason}
and RES.DELETE_REASON_ like #{taskDeleteReasonLike}
and RES.OWNER_ = #{taskOwner}
and RES.OWNER_ like #{taskOwnerLike}
and RES.ASSIGNEE_ = #{taskAssignee}
and RES.ASSIGNEE_ like #{taskAssigneeLike}
and RES.PRIORITY_ = #{taskPriority}
and RES.PRIORITY_ >= #{taskMinPriority}
and RES.PRIORITY_ <= #{taskMaxPriority}
and RES.END_TIME_ is null
and RES.END_TIME_ is not null
and HPI.END_TIME_ is not null
and HPI.END_TIME_ is null
and RES.DUE_DATE_ = #{dueDate}
and RES.DUE_DATE_ < #{dueBefore}
and RES.DUE_DATE_ > #{dueAfter}
and RES.DUE_DATE_ is null
and RES.START_TIME_ = #{creationDate}
and RES.START_TIME_ < #{creationBeforeDate}
and RES.START_TIME_ > #{creationAfterDate}
and RES.END_TIME_ = #{completedDate}
and RES.END_TIME_ < #{completedBeforeDate}
and RES.END_TIME_ > #{completedAfterDate}
and RES.CATEGORY_ = #{category}
and RES.TENANT_ID_ = #{tenantId}
and RES.TENANT_ID_ like #{tenantIdLike}
and (RES.TENANT_ID_ = '' or RES.TENANT_ID_ is null)
and RES.ASSIGNEE_ is null
and HI.TYPE_ = 'candidate'
and
(
HI.USER_ID_ = #{candidateUser}
or
HI.GROUP_ID_ IN
#{group}
)
and (
exists(select LINK.USER_ID_ from ${prefix}ACT_HI_IDENTITYLINK LINK where USER_ID_ = #{involvedUser} and LINK.TASK_ID_ = RES.ID_)
or RES.ASSIGNEE_ = #{involvedUser}
or RES.OWNER_ = #{involvedUser}
)
and A${index}.TASK_ID_ is null
and A${index}.NAME_= #{queryVar.name}
and A${index}.VAR_TYPE_ = #{queryVar.type}
and lower(A${index}.TEXT_)
and A${index}.TEXT_
LIKE
#{queryVar.textValue}
and A${index}.TEXT2_
LIKE
#{queryVar.textValue2}
and A${index}.LONG_
#{queryVar.longValue}
and A${index}.DOUBLE_
#{queryVar.doubleValue}
and (A${index}.TEXT_ is not null or A${index}.TEXT2_ is not null or A${index}.LONG_ is not null or A${index}.DOUBLE_ is not null or A${index}.BYTEARRAY_ID_ is not null)
and A${index}.TEXT_ is null and A${index}.TEXT2_ is null and A${index}.LONG_ is null and A${index}.DOUBLE_ is null and A${index}.BYTEARRAY_ID_ is null
=
=
<>
<>
>
>=
<
<=
看了这些,如果你觉得你对activiti的底层有足够的了解,你可以
完全重写或者扩展actviti中的service API。activiti就是通过这些sql映射配置来完成数据查询,当然如果你在使用过程中如果发现其中一些sql查询效率很低的话,大伙可以由针对的进行修改达到自己的要求。 现在网络上一些关于activiti也有类似的问题出现。大伙使用过程相信也会遇到。在这里就这样抛砖引玉,希望对初学的你有所帮助.......