pro*_*ick 14 php mysql pdo doctrine communication-protocol
编辑:这个题目标题最初是: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();
Run Code Online (Sandbox Code Playgroud)
或类似的:
$pdo->exec("INSERT INTO category (name) VALUES('cat')");
echo $pdo->lastInsertId();
Run Code Online (Sandbox Code Playgroud)
将导致SELECT LAST_INSERT_ID()
日志中只有一个位置(没有单独):
1701 Query INSERT INTO category (name) VALUES ('cat')
Run Code Online (Sandbox Code Playgroud)
原始问题:
我有2张桌子:
category(id,name)
product(id, name, categoryId)
Run Code Online (Sandbox Code Playgroud)
我创建了新的类别对象和产品对象.我将类别对象分配给产品对象.我没有设置任何ID:
$product = new Product();
$product->name = 'asdf';
$category = new Category();
$category->name = 'cat';
$product->Category = $category;
Run Code Online (Sandbox Code Playgroud)
之后,我刷新连接并检查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
Run Code Online (Sandbox Code Playgroud)
Doctrine如何知道,新创建的类别ID是312?日志中没有其他内容.
pro*_*ick 23
我做了一些研究并浏览了一些源代码,所以我的回答可能有点不对而且不准确.
首先,这与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
)
OK数据包在这里描述:MySQL通用响应数据包 - OK数据包