如何用 esProc 在 Java 中将 csv 当数据库表查询
Java 计算 csv 文件的代码太麻烦,借助数据库又会导致架构复杂。esProc 提供了 JDBC 驱动和计算类库,可以在 Java 中嵌入 SPL 语句,将 csv 文件当数据表直接查询,方便多了。
先下载 esProc,推荐标准版:https://www.esproc.com/download-esproc/
下载并安装相应的版本。
在配置 Java 环境前,先试试 esProc 是否安装成功。准备一个标准的 csv 文件:
打开 esProc IDE,新建脚本,在 A1 格写 SPL 语句,用来读取 csv 文件:
=file("d:/Orders.csv").import@tc()
按 ctrl-F9 执行,可以在 IDE 右边看到执行结果,文件被读成了数据表的形式,这对调试 SPL 代码很方便。
IDE 运行正常,说明 esProc 自己的环境正常,下面配置 Java 环境。
从目录 "[安装目录]\esProc\lib" 下找到 esProc JDBC 相关的 jar 包:esproc-bin-xxxx.jar、icu4j_60.3.jar。
将这两个 jar 包部署到 Java 开发环境的类路径下。
再从目录 "[安装目录]\esProc\config" 下找到 esProc 配置文件 raqsoftConfig.xml,同样部署到 Java 开发环境的类路径下。配置文件不用改也能用,其中 mainPath 定位了 csv 文件等各类文件的默认路径,可以酌情修改。
接下来,就可以编写 Java 代码,通过 esProc JDBC 执行 SPL 了:
Class.forName("com.esproc.jdbc.InternalDriver");
Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareStatement("=file(\"d:/Orders.csv\").import@tc()");
ResultSet rs = st.executeQuery();
ResultSetMetaData rsmd = rs.getMetaData();
for ( int c = 1; c <= colCount;c++) {
String title = rsmd.getColumnName(c);
if( c > 1 ) {
System.out.print("\t");
}
else {
System.out.print("\n");
}
System.out.print(title);
}
while (rs.next()) {
for(int c = 1; c<= colCount; c++) {
if ( c > 1 ) {
System.out.print("\t");
}
else {
System.out.print("\n");
}
Object o = rs.getObject(c);
System.out.print(o.toString());
}
}
if (con!=null) {
con.close();
}
前 4 行是重点,加载 esProc 驱动并执行 SPL 语句,读取 csv 文件。可以看到,这部分代码与通过数据库 JDBC 执行 SQL 的代码完全一致。
下面是执行结果:
当然,只是把数据读进来并不会减少多少 Java 工作量,我们再试试带有条件查询,并且设计一个参数,把上面 prepareStatment 那句换成下面代码:
PreparedStatement st = con.prepareStatement("=file(\"d:/Orders.csv\").import@tc().select(Amount>? && Amount<=? && like@c(Client,?))");
st.setInt(1,2000);
st.setInt(2,4000);
st.setString(3,"*s*");
查询出 Amount 在 2000 和 4000 之间,Client 含有 s 的记录,不区分大小写。执行后结果像这样:
上面是 esProc 的原生代码 SPL,esProc 也支持简单 SQL,方便数据库程序员使用。比如分组汇总查询 :
PreparedStatement st = con.prepareStatement("$select year(OrderDate) y, Client,sum(Amount) amt,count(1) cnt from d:/Orders.csv group by year(OrderDate),Client having sum(Amount)>?");
st.setInt(1,5000);
按年份、Client 分组汇总并过滤,执行后可以看到结果:
esProc 还支持计算超出内存的大 csv 文件,代码也很简单,官网有具体介绍。
英文版 https://c.esproc.com/article/1742518026310