怎样让开发的报表能不依赖数据库可移植?
一个应用系统部署时可能连接不同的数据库,这时如果报表开发中使用了某种数据库独有的语法(数据库方言),那么报表的移植性就会很差。如何增强报表在面对不同数据库时的移植性呢?
要解决这个问题就要避免使用数据库独有的语法 / 函数,一种做法是从数据库取数后在应用端使用 Java 完成报表数据准备,这样当数据源发生变化时只需要更改取数接口,数据处理算法则无需改动。不过,由于 Java(包括 Stream)缺少结构化计算类库,复杂的报表数据准备编写并不容易,即使是简单的分组汇总也要写几十行代码。为了报表的移植性使用 Java 准备数据往往得不偿失。
还有什么好办法呢?
集算器 SPL 可以很好解决这个问题。集算器是一款开源数据处理引擎,擅长结构化数据计算,计算类库丰富可以满足复杂报表数据准备工作。同时,集算器天然支持多种数据源(RDB、NoSQL、Json、CSV、Webservice 等),还可以基于不同的数据源进行混合计算。
与 Java 类似,集算器是运行在数据库外的独立计算引擎,集算器连接数据源取数后在库外分步完成报表数据准备工作,提供不依赖数据库的计算能力。数据源更改时,只需要修改取数 SPL 脚本即可,后续计算完全无缝移植。
比如要找出销售额占到一半的前 n 个客户(大客户)的订单情况。
A |
|
1 |
=db.query("select * from orders") |
2 |
=A1.groups(customer;sum(amount):amount).sort(amount:-1) |
3 |
=A2.sum(amount)/2 |
4 |
=0 |
5 |
=A2.pselect((A4=A4+amount,A4>=A3)) |
6 |
=A2.(customer).to(,A5) |
7 |
=A1.select(A6.pos(A1.customer)) |
通过分步的方式,先找到符合条件的大客户,再查询这些客户的详细订单信息。从实现的过程来看,SPL 要比原生的 Java 实现结构化数据计算简单太多。
不过,有的时候还需要数据库来完成一些计算,而不同数据库语法又不尽相同。这时可以使用 SPL 的 SQL 翻译功能,通过sql.sqltranslate(dbtype)
函数将标准 SQL 中的函数翻译成指定数据库中的格式,对应不同的数据库修改一下配置就可以。
此外,集算器可以作为嵌入式 JDBC 与报表工具集成使用,报表工具通过 JDBC 方式访问 SPL 计算结果,就像访问数据库一样。
从数据库的角度来看,SPL 更像是不依赖数据库的库外存储过程;从应用的角度来看,SPL 更像是增强型 Java 计算引擎,正因为集算器提供了不依赖数据库的完备计算能力,又弥补了 Java 计算困难的难题,才能让报表在不同数据源之间顺利移植。
英文版