如何将 SQL 数据映射到 Java JSON 对象和 JSON 数组?

Posted

技术标签:

【中文标题】如何将 SQL 数据映射到 Java JSON 对象和 JSON 数组?【英文标题】:How to map SQL data into Java JSON object and JSON array? 【发布时间】:2019-03-21 17:13:53 【问题描述】:

我正在使用 Java 构建 JSON 对象并希望将它们发送到 JSON 数组中,因为我的数据库中的数据未排序。我无法将数据映射为正确的格式。我觉得我缺乏逻辑。

下面是我的数据库表的图像,它在 mysql 中:

我要为这个表创建一个 JSON 格式,如下所示:

  [
  
    "1": "450",
    "2": "495",
    "OUTLET": "TOTTAL2",
    "BILLDATE": "",
    "TOTAL": "945"
  ,
  
    "1": "10",
    "2": "15",
    "OUTLET": "Ol1",
    "BILLDATE": "08-21-2018",
    "TOTAL": "25"
  ,
  
    "1": "20",
    "2": "25",
    "OUTLET": "ol1",
    "BILLDATE": "08-22-2018",
    "TOTAL": "45"
  ,
  
    "1": "30",
    "2": "35",
    "OUTLET": "ol1",
    "BILLDATE": "08-23-2018",
    "TOTAL": "65"
  ,
  
    "1": "40",
    "2": "45",
    "OUTLET": "ol2",
    "BILLDATE": "08-21-2018",
    "TOTAL": "85"
  ,
  
    "1": "50",
    "2": "55",
    "OUTLET": "ol2",
    "BILLDATE": "08-22-18",
    "TOTAL": "105"
  ,
  
    "1": "60",
    "2": "65",
    "OUTLET": "ol2",
    "BILLDATE": "08-23-2018",
    "TOTAL": "125"
  ,
  
    "1": "70",
    "2": "75",
    "OUTLET": "ol3",
    "BILLDATE": "08-21-2018",
    "TOTAL": "145"
  ,
  
    "1": "80",
    "2": "85",
    "OUTLET": "ol3",
    "BILLDATE": "08-22-2018",
    "TOTAL": "165"
  ,
  
    "1": "90",
    "2": "95",
    "OUTLET": "ol3",
    "BILLDATE": "08-23-201818",
    "TOTAL": "185"
  
]

上面的 JSON 是我想要的输出。但我无法在循环中映射数据,或者我没有得到逻辑。我只是想为html表创建一个JSON格式我还提供了我想要的json。

我落后的地方是编码和思考如何循环数据以获得所需格式的逻辑:

这是我要制作的表格

我知道在 java 中使用 GSON 来解析 json(在 Java 中发送 json),所以我可以做到这一点,我唯一想要的就是喜欢如何编写代码。

这是我获取第一个标头的 Java 代码

    String TotalAmountWithDateSql = "quwry1";
//          System.out.println("TotalAmountWithDateSql"+TotalAmountWithDateSql);
            String GrandTotalSql = "query2";
//          System.out.println("grandTotal"+GrandTotalSql);

            try 
                con = DBConnection.createConnection();
                statement = con.createStatement();

                ResultSet resultSet = statement.executeQuery(GrandTotalSql);

                while (resultSet.next()) 

                    map.put("OUTLET/HOURS", "  ALL");
                    GrandTotal = resultSet.getLong("TOTAL");
                    map.put("TOTAL", GrandTotal);

                    resultSet = statement.executeQuery(TotalAmountWithDateSql);
                    while (resultSet.next())

                    

                        BillTime = resultSet.getString("TIME");
                        NetAmtWithTime = resultSet.getLong("AMOUNT");
                        map.put(BillTime, NetAmtWithTime);
                    
                    list.add(map);
                    str = gson.toJson(list);
                
                System.out.println("value  " + str);
                response.setContentType("application/json");
                response.getWriter().write(str);

从我得到的这个 Java 代码

现在我想像我上传的 JSON 一样调用下面的数据,但这只是给了我第一个标题:

【问题讨论】:

I downvoted because no attempt was made,例如编写SELECT 语句,使用 JDBC、JPA 或其他方式检索数据,将数据操作为所需的形式,从一些内存数据结构生成 JSON。简而言之,就目前的问题而言,它太宽泛了 @Andreas 我正在使用来自一个查询的哈希映射我正在调用网点并将它们存储到列表中并在第一个查询的大小上运行下一个查询以获取日期但我无法循环将它们放入 。 不要试图在评论中用文字解释。 编辑问题,在那里解释显示你拥有的代码并解释具体你卡在哪里。 【参考方案1】:

让我们退后一步,尝试在 SQL 中执行所有操作。 MySQL 可以使用WITH ROLLUP(类似于标准 SQL GROUPING SETS)计算总计,您不需要两次往返。此外,MySQL(在某种程度上)支持标准SQL/JSON,因此您不必在 Java 中进行任何格式化。

首先,让我们尝试在不生成 JSON 的情况下编写 SQL 查询:

SELECT
  CASE 

    -- The label of the grand total
    WHEN GROUPING(outlet) = 1 THEN 'TOTAL2'

    -- Prevent printing the outlet on rows 2+ per outlet group
    WHEN row_number() OVER (PARTITION BY outlet ORDER BY billdate) = 1 THEN outlet 
  END AS outlet,
  billdate,
  SUM(netAmount) AS `Total1/Ho...`,

  -- This is just a silly assumption based on your data.
  -- Your actual formula might be more involved
  SUM(CASE WHEN mod(hours, 2) = 1 THEN netAmount END) AS `1`,
  SUM(CASE WHEN mod(hours, 2) = 0 THEN netAmount END) AS `2`

  -- Possibly more?
FROM t
GROUP BY outlet, billdate WITH ROLLUP

-- Get only the grand total or ordinary groupings
HAVING GROUPING(outlet) = 1 OR GROUPING(billdate) = 0

-- Possibly add ORDER BY here to get the desired ordering if that's required

接下来,我们来生成 JSON

为简单起见,我不会重写上面的整个查询,而是将其放在一个 CTE 中,这是一个方便的构造 SQL 的工具:

WITH
  t AS (
    -- Copy paste previous query here
  )
SELECT
  json_arrayagg(json_object(
     '1', t.`1`,
     '2', t.`2`,
     'OUTLET', t.outlet,
     'BILLDATE', t.billdate,
     'TOTAL', t.total
  ))
FROM t

dbfiddle here

注意,您还可以使用第三方库,例如 jOOQ、which can export data as JSON out of the box 或 which supports SQL/JSON functions(免责声明,我在 jOOQ 背后的公司工作)。

【讨论】:

【参考方案2】:

这确实很简单。您需要获取所有记录并创建一个包含地图对象的列表,其中每个地图对象将包含您想要的这五个键值对。

以下是您需要编写的代码,

public static void main(String[] args) throws IOException 
    createJson();


public static List<Map<String, String>> getMapList(ResultSet rs) throws SQLException 
    List<Map<String, String>> mapList = new ArrayList<Map<String,String>>();

    while(rs.next()) 
        Map<String, String> map = new LinkedHashMap<String, String>();
        map.put("1", rs.getString("col1"));
        map.put("2", rs.getString("col2"));
        map.put("OUTLET", rs.getString("outlet"));
        map.put("BILLDATE", rs.getString("billdate"));
        map.put("TOTAL", rs.getString("total"));
        mapList.add(map);
    
    return mapList;


public static void createJson() 
    List<Map<String, String>> mapList = new ArrayList<Map<String,String>>();

    Map<String, String> map1 = new LinkedHashMap<String, String>();
    map1.put("1", "50");
    map1.put("2", "55");
    map1.put("OUTLET", "ol2");
    map1.put("BILLDATE", "08-22-18");
    map1.put("TOTAL", "105");

    Map<String, String> map2 = new LinkedHashMap<String, String>();
    map2.put("1", "60");
    map2.put("2", "65");
    map2.put("OUTLET", "ol3");
    map2.put("BILLDATE", "08-23-18");
    map2.put("TOTAL", "125");

    mapList.add(map1);
    mapList.add(map2);

    String json = new Gson().toJson(mapList);
    System.out.println(json);

希望这会有所帮助。

【讨论】:

那么即使你可以像我硬编码一样将它们写在 hashmap 键中。您可以编写 rs.getString("yourcolumnname"),而不是硬编码“1”和“2” 当然,如果您遇到任何问题,请告诉我。您可以按原样运行我的代码,它将完全按照您的需要输出 json 字符串。 您的架构不清楚,因为您附加的图片未显示所有列。如果您可以共享架构甚至查询,我应该能够更好地帮助您。 让我们continue this discussion in chat。

以上是关于如何将 SQL 数据映射到 Java JSON 对象和 JSON 数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何将 JSON 映射到 java 模型类

Tableau + Spark SQL 连接器 + Java Spark 数据帧

如何将具有嵌套对象的复杂 json 文件映射到 java 对象?

如何使用 JPA 和 Hibernate 将 MySQL JSON 列映射到 Java 实体属性

将 MySQL JSON 列映射到休眠值类型

将一行从 SQL 数据映射到 Java 对象