[英]How does PDO know last inserted id in MySQL?
编辑:这个题目标题最初是: Doctrine如何知道MySQL中最后插入的id? 并与Doctrine ORM mapper有关。 经过一番挖掘后,我发现这个问题与Doctrine无关,而是与PDO_MySQL , MySQL C API以及最终的MySQL客户端 - 服务器通信有关。 我决定更改标题,所以也许有人会找到他/她的问题的答案。
对于那些不使用学说的人:我很好奇,为什么吼叫:
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? 日志中没有其他内容。
我做了一些研究并浏览了一些源代码,所以我的回答可能有点不对而且不准确。
首先,这与Doctrine并不真正相关。 Doctrine使用PDO_MYSQL 。 但是内部PDO_MYSQL使用与mysql_insert_id
函数相同的东西 - 本机MySQL C API函数 - mysql_insert_id
。
没有单独的SELECT LAST_INSERT_ID()
在于,在执行语句之后(在我的示例中为INSERT
),服务器响应数据以及OK包中包含的其他一些内容,包括insert_id
。 所以当我们解雇mysql_insert_id()
我们没有连接到服务器,接收insert_id
- mysql库不需要这样做 - 它已经从上次执行查询时存储了这个值(至少在分析文件libmysql.c
后我是这么认为的) libmysql.c
)
OK数据包在这里描述: MySQL通用响应数据包 - OK数据包
last_insert_id
仅适用于AUTO_INCREMENT
列。 如果您手动将值插入AUTO_INCREMENT
列,它将无法工作。
该学说将起作用,因为它就像为它分配一个NULL
(尽管你从未专门写过)。 这会触发自动增量并为last_insert_id()
提供值。
我在这里加了一个jpg,你可以看到它。 希望能帮助到你!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.