Como o PDO sabe o último ID inserido no MySQL?
-
28-09-2019 - |
Pergunta
EDITAR: Este título de pergunta foi originalmente: Como a doutrina sabe o último ID inserido no MySQL? e estava relacionado a Doutrina Mapeador orm. Depois de uma escavação, descobri que essa pergunta não está relacionada a Doutrina mas para PDO_MYSQL, Mysql C API e finalmente - para a comunicação do MySQL Client -Server. Decidi mudar o título, então talvez alguém encontre resposta para sua pergunta.
Para aqueles que não estão usando doutrina: eu estava curioso, por que abaixo:
mysql_query("INSERT INTO category (name) VALUES('cat')");
echo mysql_insert_id();
ou similar:
$pdo->exec("INSERT INTO category (name) VALUES('cat')");
echo $pdo->lastInsertId();
levará a apenas uma posição (sem separado SELECT LAST_INSERT_ID()
) no log:
1701 Query INSERT INTO category (name) VALUES ('cat')
Pergunta original:
Eu tenho 2 tabelas:
category(id,name)
product(id, name, categoryId)
Eu criei um novo objeto de categoria e objeto de produto. Eu atribuí objeto de categoria ao objeto do produto. Eu não defini nenhum IDS:
$product = new Product();
$product->name = 'asdf';
$category = new Category();
$category->name = 'cat';
$product->Category = $category;
Depois disso, liberei a conexão e verifiquei os logs do 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
Como a doutrina sabia que o ID da categoria recém -criado é 312? Não há mais nada em logs.
Solução
Fiz algumas pesquisas e naveguei algum código -fonte, para que minha resposta possa estar um pouco errada e não precisa.
Primeiro de tudo, isso não está realmente relacionado a Doutrina. Doutrina usos PDO_MYSQL. Mas internamente PDO_MYSQL usa a mesma coisa que mysql_insert_id
função - nativo Mysql C API função - mysql_insert_id
.
A razão pela qual não há separação SELECT LAST_INSERT_ID()
está no fato de que após a declaração ser executada (no meu exemplo INSERT
), o servidor responde com dados e algumas outras coisas incluídas em Ok pacote), Incluindo insert_id
. Então, quando disparamos mysql_insert_id()
Não estamos nos conectando ao servidor, para receber insert_id
- A biblioteca MySQL não precisa fazer isso - ela já possui esse valor armazenado na última execução da consulta (pelo menos acho que sim depois de analisar o arquivo libmysql.c
)
Ok pacote é descrito aqui: Pacotes de resposta genéricos do MySQL - ok pacote
Outras dicas
Provavelmente ligando http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
last_insert_id
funciona apenas para AUTO_INCREMENT
colunas. Não funcionará se você inserir um valor manualmente no AUTO_INCREMENT
coluna.
A doutrina funcionará porque é como atribuir um NULL
para isso (embora você nunca escreva isso especificamente). Isso desencadeia o incremento automático e fornece um valor para last_insert_id()
.
Eu incluí um JPG aqui para que você possa vê -lo. Espero que ajude!