14

编辑:这个问题的标题最初是:Doctrine 如何知道 MySQL 中最后插入的 id?并且与Doctrine ORM mapper 有关。经过一番挖掘,我发现这个问题与Doctrine无关,而是与PDO_MySQLMySQL C API以及最后 - 与 MySQL 客户端-服务器通信有关。我决定更改标题,所以也许有人会找到他/她的问题的答案。

对于那些不使用 Doctrine 的人:我很好奇,为什么如下:

mysql_query("INSERT INTO category (name) VALUES('cat')");
echo mysql_insert_id();

或类似的:

$pdo->exec("INSERT INTO category (name) VALUES('cat')");
echo $pdo->lastInsertId();

将导致SELECT LAST_INSERT_ID()日志中只有一个位置(没有单独的 ):

1701 Query    INSERT INTO category (name) VALUES ('cat')

原始问题:

我有 2 张桌子:

category(id,name)
product(id, name, categoryId)

我创建了新的类别对象和产品对象。我将类别对象分配给产品对象。我没有设置任何ID:

$product = new Product();
$product->name = 'asdf';

$category = new Category();
$category->name = 'cat';

$product->Category = $category;

之后,我刷新了连接并检查了 MySQL 日志:

1684 Query  START TRANSACTION
1684 Query  INSERT INTO category (name) VALUES ('cat')
1684 Query  INSERT INTO product (name, categoryid) VALUES ('asdf', '312')
1684 Query  COMMIT

Doctrine 怎么知道新创建的类别 id 是 312?日志中没有其他内容。

4

3 回答 3

23

我做了一些研究并浏览了一些源代码,所以我的答案可能有点错误且不准确。

首先,这与Doctrine并没有真正的关系。教义使用PDO_MYSQL。但在内部PDO_MYSQL使用与函数相同的东西mysql_insert_id- 本机MySQL C API函数 - mysql_insert_id

没有单独的原因SELECT LAST_INSERT_ID()在于,在执行语句后(在我的示例中INSERT),服务器响应数据和OK Packet中包含的其他一些东西),包括insert_id. 因此,当我们触发时,mysql_insert_id()我们没有连接到服务器,要接收insert_id- mysql 库不需要这样做 - 它已经从上次执行查询时存储了这个值(至少我在分析文件后是这样认为的libmysql.c

OK Packet在这里描述:MySQL Generic Response Packets - OK Packet

于 2010-11-24T20:39:31.597 回答
1

可能通过调用http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html

于 2010-11-24T13:53:39.137 回答
1

last_insert_id仅适用于AUTO_INCREMENT列。如果您手动将值插入列中,它将不起作用AUTO_INCREMENT

该学说将起作用,因为它就像NULL为它分配 a 一样(尽管您从未专门写过它)。这会触发自动增量并为last_insert_id().

我在这里包含了一个jpg,以便您可以看到它。希望能帮助到你!

在此处输入图像描述

于 2010-11-24T18:26:00.290 回答