2015-04-04 68 views
0

我有一个Java应用程序,我正在尝试对MySQL数据库进行一系列批量插入。但是,我的许多表都是通过外键链接的。所以我不知道使用外键的价值,因为它们是在上一批中生成的。Java PreparedStatement多个批量插入外键


例如采取这两个表:

ID

孩子
ID
PARENT_ID (需要外键parent.id)
名称


我知道如何导入这些不使用批次:

//already initialized variables: Connection connection, List<ParentObject> parentObjects 

ResultSet rs = null; 
PreparedStatement psParent = null; 
PreparedStatement psChild = null; 
for(ParentObject parent: parentObjects){ 
    psParent = connection.prepareStatement("INSERT INTO product (name) VALUES (?)", PreparedStatement.RETURN_GENERATED_KEYS); 
    psParent.setString(1, parent.getName()); 
    psParent.executeUpdate(); 

    int parentId = 0; 
    rs = psParent.getGeneratedKeys(); 
    if (rs.next()) 
     parentId = rs.getInt(1); 

    rs.close(); 
    psParent.close(); 

    for(ChildObject child : parent.getChildren()){ 
     psChild = connection.prepareStatement("INSERT INTO child (parent_id, name) VALUES (?,?)"); 
     psChild.setInt(1, parentId); 
     psChild.setString(2, child.getName()); 
     psChild.executeUpdate(); 
     psChild.close(); 
    } 
} 

现在我尝试使用批处理:

PreparedStatement psParent = connection.prepareStatement("INSERT INTO product (name) VALUES (?)"); 
PreparedStatement psChild = connection.prepareStatement("INSERT INTO child (parent_id, name) VALUES (?,?)"); 
for(ParentObject parent: parentObjects){ 
    psParent.setString(1, parent.getName()); 
    psParent.addBatch(); 

    for(ChildObject child : parent.getChildren()){ 
     psChild.setInt(1, I_DONT_KNOW_HOW_TO_GET_THIS_ID_WHICH_HASNT_BEEN_INSERTED_YET); 
     psChild.setString(2, parent.getName()); 
     psChild.addBatch(); 
    } 
} 

psParent.executeBatch(); 
psParent.close(); 
psChild.executeBatch(); 
psChild.close(); 

我使用的实际数据结构要复杂得多比我上面提到的要多,但它说明了基本问题。我将如何使用批次完成上述操作?我遇到的问题是,如果不先知道要使用的parent_id外键,则不能插入子对象。

我在其他地方搜索了答案,找不到任何解决方法。我读了一些关于使用存储过程的内容(如果可能,我希望避免这种情况)。效率在这里很重要,因为我正在处理数百万条记录。我很欣赏任何人可能有的见解。

+0

执行'executeBatch'之后,您可以获取生成的密钥,请参阅[这里](http://stackoverflow.com/q/4952316/3080094)。因此,首先在批处理中插入父记录,获取parent_ids,然后在批处理中插入子记录。 – vanOekel 2015-04-04 22:28:42

回答

0

不要以为生成的主键是可能的。如果您的应用程序只是数据库的一个客户端,那么您可以自己计算主键并直接在准备好的语句中传递它们。