Doktrin använder Identitetskartan mönster för att spåra objekt. Så närhelst du hämtar ett objekt från databasen, håller Doctrine en referens till detta objekt i dess UnitOfWork. Och i grund och botten använder den ID:t som en nyckel för att hantera objekt i dess UnitOfWork.
T.ex.
$objectA = $this->entityManager->find('EntityName', 1);
$objectB = $this->entityManager->find('EntityName', 1);
skulle bara avfyra en SELECT-fråga mot databasen. I det andra samtalet kommer doktrinen att kontrollera identitetskartan och hitta samma ID utan att göra en databas tur och retur. Även om du använder proxyobjekt skulle objektet ha samma ID.
Men för
$objectA = $repository->findOneBy(array('name' => 'Benjamin'));
$objectB = $repository->findOneBy(array('name' => 'Benjamin'));
du skulle se två frågor i din SQL-logg, trots att du refererar till samma objekt. Doktrin känner bara till objekt efter ID , så en fråga för ett annat kriterium måste gå till databasen, även om den kördes tidigare.
Men doktrinen är smart, den skapar inte en ny enhet utan får ID:t och ser om den redan finns i minnet.
PHP följer kopiera-på-skriv-paradigmet, det är en optimeringsprincip. En riktig kopia av en variabel görs endast när variabeln modifieras. Så minnesanvändningen för en begäran som läser objekt från databasen är densamma som för att inte behålla en variabel kopia.
Så bara när du ändrar variabler skapar dina applikationer nya variabler internt och förbrukar minne.
Så när du ringer spolning , doktrin itererar över Identiy Map och jämför varje obecjts ursprungliga egenskap med de aktuella värdena. Om ändringar upptäcks kommer den att stå i kö för en UPPDATERINGSfråga. Endast faktiskt uppdaterade fält ändras i databasen.
Hur man optimerar
Så ibland är det vettigt att markera objekt som skrivskyddade (endast infoga och ta bort), så att de inte kommer att finnas i ändringsuppsättningen (du kan göra det i din xml-mappningsfil eller med kommentarer eller i din php-kod).
$entityManager->getUnitOfWork()->markReadOnly($entity)
Eller spola bara en enhet
$entityManager->flush($entity)