将 Json 转换为 Java 对象,动态且灵活的方法是什么?

 

解决办法:esProc - Java 专业计算包

imagepng

esProc 是专门用于基于 Java 计算的类库,旨在简化 Java 代码。 SPL 是基于 esProc 计算包的脚本语言,和 Java 程序一起部署,可以理解为库外存储过程,用法和 Java 程序中调用存储过程相同,通过 JDBC 接口传递给 Java 程序执行,实现结构化计算。它非常轻巧,语法简单,类似执行 SQL 的方式计算 Json 数据,返回 ResultSet 对象。

文件 EO.json 存储一批员工信息,以及属于员工的多个订单,部分数据如下:

[{
      "_id": {"$oid":   "6074f6c7e85e8d46400dc4a7"},
      "EId": 7,"State":   "Illinois","Dept": "Sales","Name":   "Alexis","Gender": "F","Salary":   9000,"Birthday": "1972-08-16",
      "Orders": [
         {"OrderID":   70,"Client": "DSG","SellerId":   7,"Amount": 288,"OrderDate": "2009-09-30"},
         {"OrderID":   131,"Client": "FOL","SellerId":   7,"Amount": 103.2,"OrderDate": "2009-12-10"}
    ]
}
{
      "_id": {"$oid":   "6074f6c7e85e8d46400dc4a8"},
      "EId": 8,"State": "California", ...
}]

用 SPL 条件查询实现如下:


A

1

=json(file("D:\\data\\EO.json").read())

2

=A1.conj(Orders)

3

=A2.select(Amount>500 &&   Amount<=2000 && like@c(Client,"*bro*"))

上面代码先将Json读为多层的序表对象,再用conj函数合并所有订单,之后用select函数完成条件查询。

这段代码可在esProc IDE中调试执行,存为脚本文件(比如condition.dfx),通过JDBC接口在JAVA中调用,具体代码如下:

package Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class test1 {
    public static void main(String[]   args)throws Exception {
       Class.forName("com.esproc.jdbc.InternalDriver");
       Connection connection   =DriverManager.getConnection("jdbc:esproc:local://");
       Statement statement =   connection.createStatement();
       ResultSet result =   statement.executeQuery("call condition()");
       printResult(result);
       if(connection != null)   connection.close();
    }
…
}

上面的用法类似存储过程,其实 SPL 也支持类似 SQL 的用法,即无须脚本文件,直接将 SPL 嵌入 JAVA 程序,代码如下:

…
ResultSet result = statement.executeQuery("=json(file(\"D:\\data\\EO.json\").read()).conj(Orders).select(Amount>500   && Amount<=3000 && like@c(Client,\"*bro*\"))");
…

与 Java 程序集成,详情参考Java 如何调用 SPL 脚本

SPL 可以实现分组汇总和关联计算,代码如下:


A

B

1

=json(file("D:\\data\\EO.json").read())


2

=A1.conj(Orders)


3

=A2.select(Amount>1000 &&   Amount<=3000 && like@c(Client,"*s*"))

/条件查询

4

=A2.groups(year(OrderDate);sum(Amount))

/分组汇总

5

=A1.new(Name,Gender,Dept,Orders.OrderID,Orders.Client,Orders.Client,Orders.SellerId,Orders.Amount,Orders.OrderDate)

/关联计算

从上面代码可以看出,SPL语法表达能力很强,不仅可以完成常用的计算,代码简短易懂,且容易集成。SPL对点操作符的支持更直观,在实现关联计算时可直接从多层数据取值,代码更加简练。

SPL语法表达能力强,经常可以简化多层json的计算,比如:文件JSONstr.jsonrunners字段是子文档,子文档有3个字段:horseIdownerColourstrainer,其中trainer含有下级字段trainerId ownerColours是逗号分割的数组。部分数据如下:

[
   {
      "race": {
            "raceId":"1.33.1141109.2",
            "meetingId":"1.33.1141109"
      },
      ...
        "numberOfRunners": 2,
      "runners":   [
          {     "horseId":"1.00387464",
                "trainer": {
                    "trainerId":"1.00034060"
                },
            "ownerColours":"Maroon,pink,dark blue."
            },
            {   "horseId":"1.00373620",
                "trainer": {
                    "trainerId":"1.00010997"
                },
            "ownerColours":"Black,Maroon,green,pink."
            }
      ]
   },
...
]

现在要按 trainerId分组,统计每组中 ownerColours的成员个数。可用下面的SPL实现本计算。


A

1

=json(file("/workspace/JSONstr.json").read())

2

=A1(1).runners

3

=A2.groups(trainer.trainerId; ownerColours.array().count():times)

在数据源方面,SPL表现优秀,不仅有专用函数读取文件中的json,也支持读取MongoDBElasticsearchWebService等多种数据源中的Json

最后说下esProc的配置。在 esProc IDE 读写计算JsonesProc的基本功能,无需额外配置(MongoDB等数据源除外)

连接 MongoDB 计算 Json 数据,参考 用 Java 如何对 MongoDB 执行类似 SQL 的查询?

更多 Json 计算示例,参考 JSON 数据计算与入库.pdf