doctrine实体管理器flush()方法如何工作?

Aer*_*dir 6 php doctrine-orm

Doctrine文档中有以下代码:

<?php
// update_product.php <id> <new-name>
require_once "bootstrap.php";

$id = $argv[1];
$newName = $argv[2];

$product = $entityManager->find('Product', $id);

if ($product === null) {
    echo "Product $id does not exist.\n";
    exit(1);
}

$product->setName($newName);

$entityManager->flush();
Run Code Online (Sandbox Code Playgroud)

我不明白的是最后一部分,在设置产品名称后$product->setName(),$entityManager->flush()调用该方法:

$product->setName($newName);
$entityManager->flush();
Run Code Online (Sandbox Code Playgroud)

在我看来,$product变量和$entityManager变量之间没有任何联系,除了$product应该包含该$entityManager->find()方法的响应的事实.

怎样$entityManager->flush()才能读取设定的值$product->setName()

cha*_*pay 6

这是一个ORM神奇的:)

但是如果认真的话,当您使用时获取数据时Doctrine,它会向您的对象添加大量元数据.您可以自己查看这些字段只是var_dump()一个对象.

创建时flush(),Doctrine检查所有已获取数据的所有字段并对数据库进行事务处理.

初始化新对象时,它没有任何Doctrine元数据,因此您必须再调用一个方法persist()来添加它.

您也可以只是看在源代码EntityManager更好地理解它是如何工作- Doctrine是一个开源项目.


JCM*_*JCM 6

Doctrine使用Identity Map模式跟踪对象.每当从数据库中获取对象时,Doctrine都会在其UnitOfWork中保留对该对象的引用.包含所有实体引用的数组是两级深度的,并且具有键"root entity name"和"id".由于Doctrine允许复合键,因此id是所有键列的已排序序列化版本.

http://doctrine-orm.readthedocs.org/en/latest/reference/unitofwork.html

您可能会问它如何读取/写入实体的值,因为它们受到保护(如果您遵循用户指南,它们应该是这样的)!

这很简单,Doctrine使用反射.

UnityOfWork中有趣的方法,它计算实体是否有任何变化:https://github.com/doctrine/doctrine2/blob/master/lib/Doctrine/ORM/UnitOfWork.php#L560