自动连接表而不破坏Zend Framework中的默认行为

时间:2008-10-24 18:36:10

标签: php zend-framework

情况如下:我有两个模型:'动作'和'用户'。这些模型分别参考表格的“行动”和“用户”。

我的操作表包含一列user_id。此时,我需要概述所有操作以及分配给它们的用户。当我使用$action->fetchAll()时,我只拥有用户ID,因此我希望能够加入用户模型中的数据,最好不要拨打findDependentRowset()

我考虑在我的模型中创建自定义fetchAll()fetchRow()find()方法,但这会破坏默认行为。

解决此问题的最佳方法是什么?任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:14)

我在Zend Framework中设计并实现了表关系功能。

我的第一个评论是你不会使用findDependentRowset() - 如果Action有一个对用户的外键引用,你就会使用findParentRow()

$actionTable = new Action();
$actionRowset = $actionTable->fetchAll();
foreach ($actionRowset as $actionRow) {
  $userRow = $actionRow->findParentRow('User');
}

编辑:在循环中,您现在拥有$ actionRow和$ userRow对象。您可以通过更改对象字段并在对象上调用save(),通过任一对象将更改写回数据库。

您还可以使用Zend_Db_Table_Select类(在我离开项目后实现)根据Action和User之间的连接检索Rowset。

$actionTable = new Action();
$actionQuery = $actionTable->select()
  ->setIntegrityCheck(false) // allows joins
  ->from($actionTable)
  ->join('user', 'user.id = action.user_id');
$joinedRowset = $actionTable->fetchAll($actionQuery);
foreach ($joinedRowset as $joinedRow) {
  print_r($joinedRow->toArray());
}

请注意,基于连接查询的此类Rowset是只读的。您不能在Row对象中设置字段值,并调用save()将更改发布回数据库。

编辑:无法使任意连接结果集可写。考虑一个基于上面连接结果集的简单示例:

action_id  action_type  user_id  user_name
   1          Buy          1       Bill
   2          Sell         1       Bill
   3          Buy          2       Aron
   4          Sell         2       Aron

接下来,对于action_id = 1的行,我更改了来自User对象的一个​​字段:

$joinedRow->user_name = 'William';
$joinedRow->save();

问题:当我查看action_id = 2的下一行时,我应该看到'Bill'还是'Wil​​liam'?如果是'Wil​​liam',这是否意味着保存第1行必须在此结果集中的所有其他行中自动将'Bill'更新为'William'?或者是否意味着save()会自动重新运行SQL查询以从数据库中获取刷新的结果集?如果查询很耗时怎么办?

还要考虑面向对象的设计。每一行都是一个单独的对象。在一个对象上调用save()是否具有在单独对象中更改值的副作用(即使它们是同一对象集合的一部分)是否合适?这对我来说似乎是一种Content Coupling

上面的示例是一个相对简单的查询,但也允许更复杂的查询。 Zend_Db无法分析查询,旨在告知可读结果的只读结果。这也是MySQL视图无法更新的原因。

答案 1 :(得分:2)

您总是可以在数据库中创建一个为您进行连接的视图。

CREATE OR REPLACE VIEW VwAction AS
SELECT [columns]
  FROM action
  LEFT JOIN user
    ON user.id = action.user_id

然后使用

$vwAction->fetchAll();

请记住,MySQL中的视图是只读的(假设这是MySQL)

答案 2 :(得分:1)

是不是创建一个视图sql表一个很好的联合解决方案? 并在一个简单的表类之后访问它

我认为如果你的逻辑在sql中比在php中更好