Java 中如何查询计算 txt/csv?

 

Github上有很多类库都能解析txt/csv,之后可以让Hibernate写入数据库,或手工拼出insert语句入库,最后用数据库查询。这种方法可以利用SQL的强大计算能力,但结构太复杂,时效性更是差得离谱。结构简单且时效性强的工具也有,其中Tablesaw模仿了Python PandasCSVJDBC可以在文件上直接执行类SQL语句,可惜这两种工具都不成熟,很多基本计算还不支持。

既有强大计算能力,又能直接计算文件的JAVA开源库,集算器SPL是个更好的选择。

SPL可通过JDBC接口被调用,入门毫无难度。比如对txt文件里的订单分组汇总:


Class.forName("com.esproc.jdbc.InternalDriver");
Connection connection =DriverManager.getConnection("jdbc:esproc:local://");
Statement statement = connection.createStatement();
String str="=T(\"D:/data/Orders.txt\").groups(year(OrderDate);sum(Amount))";
ResultSet result = statement.executeQuery(str);

 

SPL提供了丰富的库函数,可直接完成常见的查询计算,比如:

条件查询
str="T(\"D:/data/Orders.txt\").select(Amount>1000 && Amount<=3000 && like(Client,\"*S*\"))

排序
str ="=T(\"D:/data/Orders.txt\").sort(Client,-Amount)";

去重
str="=T(\"D:/data/Orders.txt\").id(Client)";

分组汇总
str ="=T(\"D:/data/Orders.txt\").groups(year(OrderDate);sum(Amount))";

关联
str ="=join(T (\"D:/data/Orders.txt\"):O,SellerId; T(\"D:/data/Employees.txt\"):E,EId).new(O.OrderID,O.Client,O.SellerId,O.Amount,O.OrderDate,   E.Name,E.Gender,E.Dept)";

SPL支持SQL语法,可降低数据库程序员的学习成本。比如上面的分组汇总可以写作:

str="$SELECT  year(OrderDate),sum(Amount) from D:/data/Orders.txt group by year(OrderDate)"

SPL支持算法外置,修改算法时无需编译代码,适合较复杂或频繁修改的计算,可显著降低耦合性。比如:在各部门找出比本部门平均年龄小的员工。先将SPL算法存为脚本文件:


A

1

=T("Employee.csv")

2

=A1.group(DEPT;   (a=~.avg(age(BIRTHDAY)),~.select(age(BIRTHDAY)

3

=A2.conj(YOUNG)

再在JAVA代码中以存储过程的方式调用脚本文件:


Class.forName("com.esproc.jdbc.InternalDriver");
Connection connection =DriverManager.getConnection("jdbc:esproc:local://");
Statement statement = connection.createStatement();
ResultSet result = statement.executeQuery("call getYoung()");
...

 

上面是日常工作中常见的计算,还有些计算不常见,但遇到了就很头疼,好在SPL有方便的函数和灵活的语法,可轻松解决各类疑难杂症。

SPL解析各类特殊分隔符,用法简单直观。比如csv文件以双横线--为分隔符,对该文件进行条件查询:
= file("D:/Orders.txt").import@t(;,"--").select(Amount>1000 && Amount<=3000)

SPL解析不规则的文本,代码也不难。比如某文件三行对应一条记录,其中第二行还包含多个字段,将该文件整理成规范的二维表,并按第3和第4个字段排序:


A

1

=file("D:\\data.txt").import@si()

2

=A1.group((#-1)\3)

3

=A2.new(~(1):OrderID,   (line=~(2).array("\t"))(1):Client,line(2):SellerId,line(3):Amount,~(3):OrderDate   )

4

=A3.sort(_3,_4)

有些计算逻辑较为复杂,即使存储过程也难以实现,而SPL计算能力强大,可轻松解决此类问题。比如:商品在出库\入库时,日期上通常不连续,要据此计算出多种商品在指定的连续日期内的库存情况。SPL只需短短几行代码:


A

1

=file("d:/inout.txt").import@t()

2

=periods(argBeginDate,argEndDate)

3

=A1.group(product;~.align(A2,date):g)

4

=A3.news(g;A3.product,A2(#):date,ifn(in,0):in,   ifn(out,0):out, stock[-1]+in-out:stock)

SPL提供了专业的IDE,不仅有完整的调试,还能用表格的形式观察每一步的中间计算结果,特别适合设计逻辑复杂的计算:

IDEpng

SPL还支持ExcelXML、数据库、NoSQLrestful等数据源,支持大文件高性能计算,诸多特性无法一一展开详述。