【问题标题】:Batch insert to multiple tables with foreign keys using JDBC使用 JDBC 批量插入具有外键的多个表
【发布时间】:2020-03-03 12:12:24
【问题描述】:

我正在编写一个接收树结构并将其插入数据库的方法,其中每个分支都是另一个数据库表。 例如:

tree = {
    "_id": "111",
    "field1": "",
    "field2": "",
    "field3": {
        "_id": "333",
        "_parent_id": "111",
        "field3_1": "",
        "field3_2": "",
        "field3_3": [
            {
                "_id": "1",
                "_parent_id": "333",
                "field3_3_1": ""
            },
            {
                "_id": "2",
                "_parent_id": "333",
                "field3_3_1": ""
            },
            {
                "_id": "3",
                "_parent_id": "333",
                "field3_3_1": ""
            }
        ]
    }
}

应该对应于 3 个表:tree、field3 和 field3_3 - 它们在 _id 和 _parent_id 上有关系。 每个分支可以是单个值、表或对象,基本上树是对应于 PostgreSQL 数据库中的某些数据结构的动态结构。 我正在使用 jdbc 将数据插入数据库。当用户可能会提供具有多个分支或多个分支值的大树时,插入此类数据的最佳方法是什么? 我在考虑这样的声明:

                 with first_insert as(
                 insert into sample(firstname, lastname)
                 values('fai55', 'shaggk')
                 RETURNING id
                 ),

                 second_insert as(
                 insert into sample1(id, adddetails)
                 values
                 ((select id from first_insert), 'ss')
                 RETURNING user_id
                 )

但是如果内部插入应该处理大批量记录(field3_3 将包含每个数据行的 100k 条记录),问题就会出现。

我已经使用 PreparedStatement 和 executeBatch() 在单个数据库级别实现了接受表和插入的方法,并且效果很好。类似这种方法的任何东西,可用于树?

【问题讨论】:

    标签: java jdbc insert batch-processing relation


    【解决方案1】:

    如果树是动态结构,我认为您必须将收到的 json 解析为可以在 Java 中工作的内容。

    这样的事情可以使用和JSONObject来实现。假设你在String data 中序列化了传入的 json。然后你可以使用:

    JSONObject dataJson = new JSONObject(data);
    

    现在您可以在 Java 中使用这种树结构了。您可以使用dataJson.toString() 将其序列化回来或创建自定义序列化程序。

    如果问题是插入大小,您可以循环 dataJson 并将其拆分为合理的块。例如你可以使用这样的东西

            JSONArray jsonArr = dataJson.getJSONArray("field3");
            JSONArray dataAccumJsonArr = new JSONArray();
            for (int i = 0; i < jsonArr.length(); i++) {
                dataAccumJsonArr.put(jsonArr.get(i));
                if (dataAccum.length() > 999) {
                    doInsert(dataAccumJsonArr);
                    dataAccumJsonArr = new JSONArray();
                }
            }
            doInsert(dataAccumJsonArr);
    

    【讨论】:

      【解决方案2】:

      我已经通过以下方式解决了这个问题: 我从树的一级获取元素,并将其所有非对象值插入到preparedStatement 批处理中(它们在一个表中),返回插入的记录ID。然后我获取每个插入元素的子元素,分配正确的 parent_id 并将它们批量插入另一个表和另一个表。效果很好!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-10-09
        • 2013-05-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多