批处理MySQL插入,一个是主记录,一个是带有外键的详细记录

时间:2013-11-03 16:25:32

标签: java mysql jdbc

我有一个将大量数据记录到MySQL数据库的应用程序。生产中的版本已经批量运行插入语句以提高性能。我们正在更改db模式,以便将一些无关的数据发送到我们可以在查找时加入的不同表。

但是,我正在尝试正确设计查询以使用我们的批处理系统。我想使用mysql LAST_QUERY_ID所以我不必担心获取生成的密钥并将它们匹配(这似乎是一项非常困难的任务)。

但是,我似乎无法找到向批处理中添加不同插入语句的方法,那么如何解决这个问题呢?我假设我需要构建第二个批处理并向其添加所有详细信息查询,但这意味着LAST_QUERY_ID失去了意义。

s = conn.prepareStatement("INSERT INTO mytable (stuff) VALUES (?)");
while (!queue.isEmpty()){
    s.setLong(1, System.currentTimeMillis() / 1000L);
    // ... set other data
    s.addBatch();

    // Add insert query for extra data if needed
    if( a.getData() != null && !a.getData().isEmpty() ){
        s = conn.prepareStatement("INSERT INTO mytable_details (stuff_id,morestuff)
                                   VALUES (LAST_INSERT_ID(),?)");
        s.setString(1, a.getData());
        s.addBatch();
    }
}

2 个答案:

答案 0 :(得分:0)

我现在已经修好了,虽然我希望有更好的方法。我构建了一个额外数据值的arraylist,我可以将其与批量插入返回的generatedKeys相关联。在第一个查询批处理执行后,我使用正确的ids / data构建第二个批处理。

答案 1 :(得分:0)

这不是批处理的工作原理。仅在一个Statement内进行批处理,对于PreparedStatement,这意味着您只能为同一个语句添加批量参数。您的代码也忽略了执行语句。

对于您想要做的事情,您应该使用setAutoCommit(false),执行两个语句然后执行commit()(或者如果发生错误则回滚)。

另外,我建议您研究检索生成密钥的JDBC标准方法,因为这会使您的代码减少MySQL特定。另请参阅Retrieving AUTO_INCREMENT Column Values through JDBC