BIRT报表的数据库间动态关联解决办法

客户在使用BIRT报表的过程中遇到了数据库间动态关联的麻烦,用BIRT的跨库关联工具以及DB2的Federated Database都难以解决。客户报表全名为“ATM关键数据查询报表”,需要通过时间段和维度等参数来显示银行ATM的统计数据和交易明细。

交易明细属于生产系统,存储于生产机的DB2的trade表中,主要字段包括runningNo(记录流水号),network(交易网点编号),outAccount(转出帐号),inAccount(转入帐号),amount(交易金额)等。这些字段关联着一些表,但这些关联表不在生产数据库中,而在另一个DB2业务数据库中。例如:交易网点编号关联的是业务库的网点表network,其主要字段包括networkCode(网点编号)、networkName(网点名)、agency (分理处名),subBranch (支行名),branch(分行名)等;转出账号和转入账号关联的是帐户表account,其主要字段包括accountNo(账号),name(用户姓名),gender(性别),occupation(职业),city(所在城市)等。

实际的trade表还有很多关联字段,包括ATM设备代码、交易类型、凭证号等,它们各自关联着不同的表。除了关联字段,trade表中还有信息字段,如交易时间、手续费、是否检测到伪钞等。

所谓“动态关联”,是指用户在前台界面输入参数,报表通过参数来决定trade和哪张表做关联,并在报表中显示关联后的数据,实际运算中可能还要进行数据过滤和汇总。

例如,用户输入:

1.trade的关联字段(tradeJoinField): outAccount
2.关联表的表名crossTable: account
3.关联表的关联字段crossJoinField: accountNo
4.关联表的其他显示字段crossOtherFields: name,gender,occupation,city

报表根据上述参数,能动态地将trade中的outAccount字段和account中的accountNo字段关联,最后显示trade中的所有字段以及account的name,gender,occupation,city字段。

如果trade和account在同一个DB2中,这个问题不算麻烦,参数可以动态拼成一个字符串SQL:

select trade.runningNo, trade.network, trade.outAccount,trade.inAccount, trade.outAccount, trade.amount, account.name, account.gender,account.occupation, account.city。用JDBC执行即可。

但现在两张表不在同一个数据库里,这就产生了动态跨库的问题。为了解决这个问题,用户尝试了四套方案:DB2 Federated Database、BIRT Data Sources Join、ETL、BIRT JAVA bean data source,,只是最后都被否了。

DB2 Federated Database和BIRT Data Sources Join是DB2、birt自带的解决方案,所以最先被尝试。DB2 Federated Database的问题在于配置困难、性能低、不稳定,而这个报表对性能和稳定性要求较高,所以未被采用;而BIRT Data Sources Join要求表名和字段名是已知、确定的,但这张报表是通过参数来动态关联的,因此也无法使用。

我们还可以用ETL把生产库的数据抽取到业务库,这样跨库的问题就转化为同库了。这个方案思路简单但实施起来细节上有很多难点,首先是实时查询。为了实时查询数据,需要在生产库使用触发器之类的功能来检测数据的实时变化,并将数据推送到业务库,但生产库不能轻易改动,因此实时查询就无法实现。非实时查询也难以办到,这是因为生产库的数据极其庞大,不可能每次都全部取过来,只有用增量抽取的办法,而判断增量就需要在trade表中加入时间戳字段。同样,生产库是不允许有这种改动的,因此本方案被pass了。

从能力上讲,BIRT JAVA bean data source是真正能解决报表问题的,它比DB2 Federated Database更稳定,比Data Sources Join更灵活性,也不需要修改生产库。这个方案只有一个缺陷:代码过于复杂。数据计算并非JAVA特长,代码复杂是正常的,但用户还有不少类似的报表,他们不愿每次遇到跨库问题都用JAVA来实现。

集算器是批量数据计算语言,也支持异种数据源之间的计算,比较适合进行动态关联计算,事实上,可以把 集算器看作是语法更简单的BIRT JAVA bean data source。

用户最终采纳了该方案。以下是简化的代码:


A1:从生产库的trade table取数据。实际上,本报表的数据量较大,应该过滤数据并使用集算器专门针对大数据的游标分段算法,此处省略了。
A2:动态拼SQL语句。
A3:从业务库用动态取数据。
A4:动态关联计算。注意,这里的${crossJoinField}和A2中的crossJoinField不同。前者是宏,是表达式的一部分;后者是普通参数,仅仅是字符串。对于外界来说这是同一个参数,代码中则由程序员自由决定是否加“${}”。
A5-A7:给关联表的其他显示字段加前缀,比如将“name,gender,occupation,city”变成“cross.name, cross.gender, cross.occupation, cross.city”。熟练了后可以将这三句写成一句:crossOtherFields.array().("cross."+~).string@d()。
A8:从A4的关联结果中取出所需的字段,形成二维表。这里的${A7}也是宏。
A9:将A8中的二维表通过JDBC返回报表工具或JAVA程序。
集算器的参数用法很灵活,比较适合这类动态关联查询。由于它是专门的计算语言,所以跨库计算的代码更加精炼易懂。JDBC输出是另一个好用的功能,这使它可以直接被BIRT调用。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值