有时我们不能使用数据库而采用文件系统存储数据,这时就需要自行完成基于文件的数据计算。但JAVA本身缺少相应的类库,需要硬编码才能实现结构化文件计算,代码复杂且可读性差。在网上有许多寻找用于文件计算的Java类库的问题,如:
http://www.coderanch.com/t/561180/java/java/read-text-file-perform-operation
http://stackoverflow.com/questions/26418282/get-text-file-through-sql-java
https://plus.google.com/112275790033275716955/posts/4p75NJYzMcv
http://stackoverflow.com/questions/28969897/file-based-datastructure-for-java
使用免费的集算器可以弥补这一不足。集算器封装了丰富的结构化文件计算函数,并提供JDBC接口。JAVA应用程序可以将集算器脚本文件当做数据库存储过程执行,传入参数并用JDBC获得返回结果。
集算器与Java应用程序的集成结构如下:
下面以文本文件的条件查询为例说明Java调用集算器完成结构化文件计算的过程。源数据如下:
条件查询:选出某时间段内的订单。
代码:
解释:
A1:读入文件。默认分隔符是tab,@t表示将第一行读为列头。
A2:执行条件查询。startDate和endDate是输入参数,比如2010-01-01至2010-12-31。结果:
JAVA主程序可以JDBC的方式调用集算器脚本,代码如下:
Class.forName("com.esproc.jdbc.InternalDriver");
con=DriverManager.getConnection("jdbc:esproc:local://");
//调用集算器脚本(类似存储过程),其中orderQuery是dfx的文件名
st=(com. esproc.jdbc.InternalCStatement)con.prepareCall("call orderQuery(?,?)");
st.setObject(1,"2010-01-01");
st.setObject(2,"2010-12-31");
//执行脚本
st.execute();
//获取结果集
ResultSetrs = st.getResultSet();
……
返回值是符合JDBC标准的ResultSet对象,调用集算器脚本和访问数据库的方法完全一样,熟悉JDBC的程序员可以很快掌握。
对于上面这类较简单的代码,还可以直接将脚本写在JDBC调用中,多行语句之间用\n分隔即可,类似执行一句较复杂的SQL,这样可以不必再保存一个脚本文件。
st = (com.esproc.jdbc.InternalCStatement)con.createStatement();
ResultSet rs1 =st.executeQuery("=file(\"D:\\sOrder.txt\")[email protected]()\n"
+ "=A1.select(OrderDate>=date(\"2010-01-01\")&& OrderDate<=date(\"2010-12-31\"))");
集算器会返回最后一个表达式的值。
关于集算器JDBC的部署和调用的更详细信息可参考【集算器集成应用之被JAVA调用】
作为专业的结构化计算类库,集算器还可以实现更多运算,下面分别举例。
排序:按照客户代码降序排序,按照年、月升序排序。
代码:=A1.sort(-Client,year(OrderDate),month(OrderDate))
解释:降序排列使用“-”,年、月需要计算获得。
引申:如果要在查询的基础上排序,可以写作=A2.sort(…),或者=A1.select(…).sort(…)
结果:
分组汇总:计算出每个销售员每年的销售额和订单数
代码:=A1.groups(SellerId,year(OrderDate);sum(Amount),count(~))
解释:函数group可在分组的同时进行汇总,~表示每组或当前组,count(~)等于count(OrderID)。
结果:
获得唯一值:列出客户名单
代码:=A1.id(Client)
结果:
去除重复:保留每个客户每个销售的第一条记录
代码:[email protected](Client,SellerId)
解释:函数group用来分组(可以不汇总),@1表示每组取第1条记录。
结果:
TopN:找到每个销售员销售额最大的3笔订单。
代码:=A1.group(SellerId;~.top(3,-Amount):t).conj(t)
解释:函数top过滤出TopN,”-”表示逆序,函数conj用于合并。
引申:如果只取最大的一笔订单,可以用maxp函数。
计算结果:
关联计算:将emp.txt的Name、Dept、Gender这三个字段对齐到sOrder.txt。
代码:
解释:
A3:函数join执行连接运算,并将两个表改名为s和e,@1表示左连接。结果如下:
引申:@1表示左链接,@f表示全连接,内连接无选项。
A4:从连接的表中取得需要的字段,组成新的结构化二维表格。
结果:
前面的例子假定文件较小,如果文件较大无法放入内存,可用集算器游标进行计算,详情参考相关文档。
值得一提的是,上述这些集算器的功能都是免费的,程序员可以无成本地将集算器引擎嵌入到自己的应用程序中。