Platform7中BPS分布式结合业务表查询示例

5年前

当业务表和流程表分开在不同的数据源时,结合业务表的任务列表查询实现起来就比较麻烦。需要用到流程的冗余表,并调用对应的构件。

本文的附件:下载


当业务表和流程表分开在不同的数据源时,结合业务表的任务列表查询实现起来就比较麻烦。需要用到流程的冗余表,并调用对应的构件。


产品帮助文档里只有对BPS ForJava场景下的介绍,本文基于Platform7 sp1产品,介绍两种实现方法及注意点,详细说明如下:


1、创建业务表,配置多数据源

以报销单信息表为例,oracle数据库脚本如下:

-- Create table

drop table EXPENSEINFO;

create table EXPENSEINFO

(

 EXPID            NUMERIC(18) not null,

 PROCESSINSTID  NUMERIC(18) not null,

 EXPNAME         VARCHAR(20) not null,

 EXPMONEY       NUMBER not null,

 REASON          VARCHAR(255),

 ISBUDGETITEM    CHAR(1),

RECORDDATE     DATE,

 AUDITOR          VARCHAR(20)

);

alter table EXPENSEINFO  add constraint P_EXP primary key (EXPID);

-- Add comments to the columns

comment on column EXPENSEINFO.EXPID

 is '报销单编号';

comment on column EXPENSEINFO.PROCESSINSTID

 is '流程实例ID';

comment on column EXPENSEINFO.EXPNAME

 is '报销人';

comment on column EXPENSEINFO.EXPMONEY

 is '报销金额';

comment on column EXPENSEINFO.REASON

 is '报销原因';

comment on column EXPENSEINFO.ISBUDGETITEM

 is '是否预算内项目';

comment on column EXPENSEINFO.RECORDDATE

 is '记录日期';

comment on column EXPENSEINFO.AUDITOR

 is '审阅人';


在Platform Governor的配置—数据源中增加业务数据源testdb,在EOS Studio的构件包配置文件contribution.eosinf文件中增加对数据源引用关系的配置:

<configValue key="testdb">testdb</configValue>

即对业务数据的数据库操作,数据源使用testdb这个key值。


2、创建流程及组织机构

利用SEE系统创建组织机构和人员信息,在EOS Studio的组织模型中刷新出来:



附带的源代码中使用了id为61的用户,需要根据实际情况修改对应的值。

本文只是为了演示分布式情况下流程的创建及启动,以及待处理任务列表的查询,所以创建一个简单流程,如下所示:



3、导入实体配置映射关系

在查询待处理任务时,需要显示业务数据:EXPNAME,EXPMONEY,RECORDDATE,就需要将它们同步冗余到流程库中的冗余表WFBizMapping中,手工配置业务表与BPS冗余表之间的字段映射,如下所示。



注意:映射表支持字符串,数字和时间格式,字段大小写敏感,写法是:vcColumn1,nmColumn1,dtColumn1,如果每种类型有多个(最多10个),后面的数字递增。业务数据会被冗余到WFBizInfo表中,可从该表中查看到“WFFIELDNAME”字段信息。


在数据建模中将业务表EXPENSEINFO导入到数据实体中。


4、启动流程实例时插入冗余的业务数据

启动流程时,需要先将冗余的业务数据封装成Map,调用对应的构件将冗余数据插入到WFBizInfo表中,本文在逻辑流testStart.biz中模拟操作,以常量模拟将要保存的报销单EXPENSEINFO信息,实现方法如下,详细情况可参看附带的源代码。


a)      构造Map对象时

注意:

l  如果利用赋值图元构造Map,除了要在变量中定义Map类型,还要对Map实例化。

l  Map中的业务数据对应的Key值必须是大写的,比如EXPNAME。

l  WFBizInfo表中dtColumn系列字段是TIMESTAMP类型,在Map中put“RECORDDATE”对应的值时,只支持“yyyyMMddHHmmss”格式的字符串。如果是“yyyy-MM-dd HH:mm:ss”格式的字符串,保存的时间是错误的。


b)      创建、启动流程实例,结束工作项时,调用的方法如下:

ProcessInstManagerService.createProcessInstance 创建流程实例,得到流程实例ID

ProcessInstManagerService.startProcessInstanceWithBizInfo 启动流程实例,将构造的Map业务数据冗余到WFBizInfo表中

ActivityInstManagerService.findLastActivityInstByActivityID4SDO 根据流程实例ID,活动定义ID查询该活动最近的活动实例

WorkItemManagerService.queryWorkItemsByActivityInstID4SDO 根据最近的活动实例ID查询出工作项,流程中“填写报销单”只有一个工作项

WorkItemManagerService.finishWorkItem 结束工作项

注意:

l  以上第2个,第3个如果调用的是不带“4SDO”的方法,所得到的是Java类型,在逻辑流中不方便处理,一般BPS For Java场景下会调用。

l  在保存业务数据到WFBizInfo中时,客户环境中曾出现特殊情况:流程实例ID和表名可以保存,但是业务字段数据无法保存,解决办法:在WFBizMapping中配置“BIZTABLENAME”时,在表名前加上所在数据库用户的名字,比如TESTDB. EXPENSEINFO,调用的构件中业务表名的输入与其保持一致。在本机测试时,未重现这种特殊情况。


5、结合业务表查询(以待处理任务列表为例)


a)      使用WorklistQueryManagerService.queryPersonWorkItemsWithBizInfo

根据where sql语句,将业务过滤条件和工作项过滤条件按顺序构造在List中,详细代码在逻辑流testQueryWithBizInfo.bizx中。

注意:

l  业务表必须要有where sql语句(即第6个参数bizSql不能为空),而且过滤字段必须是冗余的字段,可以是其中的部分字段。

l  第8个参数bizBindList实例化后,要根据bizSql的顺序往bizBindList中add值。对于日期字段,要设置的值必须是java.util.Date类型,不能是字符串类型。

l  工作项可以不设置条件,第5个参数wiSql可以设置为:

1=1   常量

常量

null   表达式

l  即使没有工作项条件,第7个参数wiBindList也不能为空,需要实例化一个空的List

l  分页对象page应该定义为Java浏览中的com.primeton.workflow.api.PageCond类型,可以为空,查询出所有记录

l  返回值类型是List<WFWorkItem>,业务信息会放在每条WFWorkItem的bizObject属性中,该属性是HashMap类型,冗余信息中的TIMESTAMP类型(oracle.sql.TIMESTAMP)会被转换为(java.sql.Timestamp),如下图所示。



b)      使用WorklistQueryManagerService.queryPersonBizEntities4SDO

可以将WFBizInfo映射成持久化实体,作为业务数据的来源表,与工作项表根据流程实例ID关联,构造criteriaType类型对象来查询出任务列表。详细代码在逻辑流testQuery4SDO.bizx中。

注意:

l  分别定义两个criteriaType类型对象,一个用来构造Wfbizinfo的查询条件,一个用来构造WFWorkItem的查询条件。

l  可以不设置过滤条件,如果要在_expr中设置过滤条件,对于Wfbizinfo中的dtcolumn系列的字段,值既可以为字符串,也可以为java.util.Date类型。

l  返回值是WFWorkItem类型的数组,业务信息会放在每条WFWorkItem的bizObject属性中,该属性是Wfbizinfo类型,冗余对象中的TIMESTAMP类型未被解析,仍然是oracle.sql.TIMESTAMP类型,如下图所示。



l  在页面上要显示日期时,需要进行转换。自定义了运算逻辑TimeTest.getDate,可以将TIMESTAMP类型数据转换成java.util.Date类型的数据。


说明:使用源代码时,多数据源的配置要根据实际情况修改;根据所建立的组织机构信息,修改构件中对应的值;启动Server后,利用逻辑流空白处的“启动调试”就可以测试。

COMMENTS

7 个回应

Normal

bigdabao 2014年08月20日 09:20

回复


Normal

自由的风 2015年11月05日 08:38

b) 创建、启动流程实例,结束工作项时,调用的方法

这个步骤中,ActivityInstManagerService.findLastActivityInstByActivityID4SDO 根据流程实例ID,活动定义ID查询该活动最近的活动实例中,活动定义ID怎么获取啊?

回复


Normal

brewstar 2015年11月05日 09:48

@自由的风:活动定义ID就是流程图中人工活动的基本属性“活动 ID”,缺省是类似manualActivity,manualActivity1,可以根据业务含义修改。

回复


Normal

自由的风 2015年11月05日 09:54

@brewstar :按照你说的步骤配置完以后,执行的时候报了个错如下:

ErrCode: 21000000
Message: (Business table mapping configuration error)

这个大概是因为什么报的错呢?

回复


Normal

brewstar 2015年11月05日 10:18

@自由的风 :错误提示业务映射表配置错误。调用startProcessInstanceWithBizInfo方法时,倒数第二个参数应该是WFBizMapping表中的表名“EXPENSEINFO”。你是用BPS产品来开发,可以参考studio的联机帮助:BPS帮助文档——开发参考——BPS应用开发指南——结合业务查询-分布式。

回复


Normal

自由的风 2015年11月05日 10:23

@brewstar :非常感谢!

回复


Normal

自由的风 2015年11月13日 14:26

你好,再问下,我今天试用了一下分布式事务,到DataObject dobj = bean.findLastActivityInstByActivityID4SDO(processInstId, "manualActivity");

这一行的时候报错如下:

Caused by: ErrCode: 21000000
Message: ( Can't find process instance , id : 3)

感觉好像是事务没提交的时候,查不到最近的活动实例。这个该如何处理啊?

回复


需要 后方可回复
如果没有账号可以 一个帐号。