在我的应用程序中,我有一个组件从另一个组件接收对象并将它们插入MySQL DB。目前我正在缓冲对象,偶尔(几秒钟)使用批处理(使用JDBC,而不是休眠)将对象插入到数据库中。
我想将这个对象分解为2个对象,然后是两个缓冲区,最后将它们插入到2个不同的表中。
我的第一个想法是使用MySQL自动生成的ID将表中的两个子对象绑定在一起(作为外键)。
我的问题是 - 当我插入'child'对象时,如何知道'father'对象的自动生成的ID?
我的想法是:
LAST_INSERT_ID();
答案 0 :(得分:1)
一种解决方案是将两条记录插入到与此问题相同的事务中。 JDBC: foreign key on PK created in same transaction
那是:
答案 1 :(得分:0)
也许这会有所帮助(您也可以在纯SQL中使用LAST_INSERT_ID(),而不仅仅是在程序内部),另请参阅http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html:
INSERT INTO foo (auto,text) VALUES(NULL,'text'); # generate ID by inserting NULL
INSERT INTO foo2 (id,text) VALUES(LAST_INSERT_ID(),'text'); # use ID in second table
鉴于OP在不同的线程上运行INSERT,需要预先分配ID - 您可以使用序列来安全地选择唯一ID(另请参阅MySQL information functions):
创建一个表来保存序列计数器并对其进行初始化:
的MySQL> CREATE TABLE序列(id INT NOT NULL);
的MySQL> INSERT INTO序列值(0);
使用该表生成如下序列号:
的MySQL> UPDATE序列SET id = LAST_INSERT_ID(id + 1);
的MySQL> SELECT LAST_INSERT_ID();
答案 2 :(得分:0)
两种方法都有效。
Java方法与数据库无关,可能更容易切换数据库或支持多个数据库供应商。
答案 3 :(得分:0)
您的基本问题是,在存储其他对象之前,您需要数据库中有关一个对象的信息。
假设您将复合对象拆分为两个较小的对象,即Place和Map。
如果您必须有两个缓冲区来存储Place和Map,那么我会看到三种方法:
只将Place放入商店缓冲区。存储Place并且已从数据库中读取PK时,只需将Map放在另一个存储缓冲区中。
将Place和Map放在他们自己的商店缓冲区中。当即将存储地图时,检查它是否与相关联的地方,以查看是否已生成PK。如果有,则存储地图。如果没有,则跳过该地图并检查下一个地图。
放置在商店缓冲区中。存储后,读取PK,并立即存储Map。这显然不使用两个存储缓冲区。
查看应用程序中其他对象的存储方式。当然,在将它们存储在数据库中之前,它们不会生成自己的ID。当然,在获得存储它们所需的所有信息之前,不要尝试将它们放在存储缓冲区中。因此,我推荐的行动方案是选项1或3。
答案 4 :(得分:0)
使用JDBC检索生成密钥的标准接口是在语句中使用getGeneratedKeys()
方法。请参阅MySQL站点的Example 21.8. Connector/J: Retrieving AUTO_INCREMENT column values using