保湿数据库

时间:2013-07-13 12:08:54

标签: zend-framework2

我是学习和理解水化如何工作的新手,只是想先指出这一点。我现在能够毫无问题地水合选择和插入查询。

我目前正在尝试水合更新查询。在我的实体中,我为数据库中的每种类型的列设置了get / set选项。我发现ObjectProperty()Hydrator也适用于我的情况。

然而,每当我尝试仅更新一定数量的列并通过水化器提取时,我就会收到错误,因为所有其他选项都没有设置并返回空值。我不需要更新特定行的所有内容,只需几列。

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

  • 名称
  • PHONE_NUMBER
  • EMAIL_ADDRESS

但我只需要更新phone_number。

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

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

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

我一直在寻找和阅读文档,但我找不到任何可以解释我做错的事情。我应该注意到我只使用Zend \ Db(Not Doctrine)。

我假设我错过了某些地方,因为我对这个我想要了解的新功能缺乏了解。

也许你没有水合更新查询......我有点迷茫/困惑。任何帮助,将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:3)

我认为你对水合作用存在根本的误解。水化器简单地从数据(水合物)填充实体对象,并从实体对象(提取)中提取数据。因此,对于不同类型的查询,没有单独的水合器。

在更新示例中,您应首先检索完整的实体对象($ 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));
}

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