如何用 esProc 在 Java 中将 csv 当数据库表查询

 

Java 计算 csv 文件的代码太麻烦,借助数据库又会导致架构复杂。esProc 提供了 JDBC 驱动和计算类库,可以在 Java 中嵌入 SPL 语句,将 csv 文件当数据表直接查询,方便多了。

先下载 esProc,推荐标准版:https://www.esproc.com/download-esproc/

下载并安装相应的版本。

在配置 Java 环境前,先试试 esProc 是否安装成功。准备一个标准的 csv 文件:

Picture1png
打开 esProc IDE,新建脚本,在 A1 格写 SPL 语句,用来读取 csv 文件:

=file("d:/Orders.csv").import@tc()

按 ctrl-F9 执行,可以在 IDE 右边看到执行结果,文件被读成了数据表的形式,这对调试 SPL 代码很方便。

Picture2png
IDE 运行正常,说明 esProc 自己的环境正常,下面配置 Java 环境。
从目录 "[安装目录]\esProc\lib" 下找到 esProc JDBC 相关的 jar 包:esproc-bin-xxxx.jar、icu4j_60.3.jar。

Picture3png
将这两个 jar 包部署到 Java 开发环境的类路径下。
再从目录 "[安装目录]\esProc\config" 下找到 esProc 配置文件 raqsoftConfig.xml,同样部署到 Java 开发环境的类路径下。配置文件不用改也能用,其中 mainPath 定位了 csv 文件等各类文件的默认路径,可以酌情修改。

Picture4png
接下来,就可以编写 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 的代码完全一致。
下面是执行结果:

Picture5png
当然,只是把数据读进来并不会减少多少 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 的记录,不区分大小写。执行后结果像这样:

Picture6png
上面是 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 分组汇总并过滤,执行后可以看到结果:

Picture7png
esProc 还支持计算超出内存的大 csv 文件,代码也很简单,官网有具体介绍。