1

我刚开始学习和理解水合作用的工作原理,只是想先指出这一点。我目前能够 Hydrate Select 和 Insert 查询没有任何问题。

我目前正忙于尝试 Hydrate Update 查询。在我的实体中,我为数据库中的每种类型的列设置了获取/设置选项。我发现 ObjectProperty() Hydrator 也最适合我的情况。

但是,每当我尝试仅更新一组列并通过水合器提取时,我都会遇到错误,因为所有其他选项都没有设置并且返回空值。我不需要更新特定行的所有内容,只需更新几列。

例如在我的数据库表中,我可能有:

  • 姓名
  • 电话号码
  • 电子邮件地址

但我只需要更新phone_number。

$entity_passport = $this->getEntityPassport();
$entity_passport->setPrimaryPhone('5551239876');

$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
    'employeeid' => '1'
));

这将返回错误,因为 setName() 和 setEmailAddress() 未包含在此更新中,并且查询返回值不能为空。但很明显,当您查看数据库表时,那里已经有数据了。那里的数据也不需要更改,仅在此示例中更改 PrimaryPhone() 号码。

我一直在到处寻找和阅读文档,但我找不到任何可以解释我做错了什么的东西。我应该注意我只使用 Zend\Db(不是 Doctrine)。

我假设我错过了某个地方,因为我对我试图理解的这个新功能缺乏了解。

也许您没有 Hydrate Update 查询...我有点迷茫/困惑。任何帮助,将不胜感激。谢谢!

4

1 回答 1

3

我认为你对补水有一个基本的误解。水合器只是从数据中填充实体对象(水合物)并从实体对象中提取数据(提取)。因此,对于不同类型的查询,没有单独的 hydrator。

在您的更新示例中,您应该首先检索完整的实体对象 ($entity_passport),然后将其传递给 TableGateway 的更新方法。您将通过employeeid 检索实体,因为这是您用来更新的条件。所以是这样的:

$entity_passport = $passportMapper->findByEmployeeId(1);
$entity_passport->setPrimaryPhone('5551239876');

$this->getTablePassport()->update($this->getHydrator()->extract($entity_passport), array(
    'employeeid' => $entity_passport->getId()
));

这是假设您有某种映射器层。否则,您可以使用您的护照 TableGateway (我假设这就是 getTablePassport() 返回的内容,不是吗?)。

否则,如果您认为检索对象的开销太大而只想运行查询,则可以只使用 \Zend\Db\Sql\Sql 对象,即:

$sql =  new \Zend\Db\Sql\Sql($dbAdapter);
$update = $sql->update('passport')
->set(array('primary_phone' => $entity_passport->getPrimaryPhone()))
->where(array('employeeid' => $employeeId));

编辑: 也许调出映射器是一个错误,因为它可能会引起更多的混乱。您可以简单地使用 TableGateway 来检索实体对象,然后对返回的行进行水合:

$rows = $this->getTablePassport()->select(array('employeeid' => 1));
$entity_passport = $this->getHydrator($rows->current());
[...]

编辑2: 我检查了你的要点,我注意到了一些事情,所以我们开始吧:

我看到您的 getTablePassport 确实返回了一个对象,它是 TableGateway 的子类。您已经为它设置了这个类以使用 HydratingResultset。这意味着您在使用网关检索对象时不需要进行任何手动补水。您还已经在同一个类中实现了一个 Search 方法,那么为什么不直接使用它呢?但是我会更改该方法,因为现在您对每一列都使用 LIKE 。它不仅效率很低,而且还会给你错误的结果,例如在 id 列上。

如果您要修复该方法,那么您可以简单地在 Service 对象中调用它: $this->getTablePassport->Search(array('employeeid' => 1));

否则,您可以在该 tablegateway 类中实现一个单独的方法,例如

public function findByEmployeeId($employeeId)
{
  return $tableGateway->select(array('employeeid' => $employeeId));
}

这应该已经返回了一组实体(或在这种特定情况下为一个)。PS 确保在检索实体时调试并检查实际返回的内容。因此,在尝试更新之前 print_r 从 PassportTable 返回的实体。您首先必须确保检索代码运行良好。

于 2013-07-13T19:47:58.683 回答