自动连接表而不破坏 Zend Framework 中的默认行为
-
04-07-2019 - |
题
情况如下:我有 2 个型号:“操作”和“用户”。这些模型分别引用表“actions”和“users”。
我的操作表包含一列 user_id
. 。目前,我需要了解所有操作以及分配给这些操作的用户。当我使用 $action->fetchAll()
, ,我只有用户 ID,所以我希望能够从用户模型中加入数据,最好不要调用 findDependentRowset()
.
我考虑过创建自定义 fetchAll()
, fetchRow()
和 find()
我的模型中的方法,但这会破坏默认行为。
解决这个问题的最佳方法是什么?任何帮助将不胜感激。
解决方案
我在 Zend Framework 中设计并实现了表关系功能。
我的第一条评论是你不会使用 findDependentRowset()
不管怎样——你会用 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());
}
请注意,此类基于联接查询的行集是只读的。您不能在 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”还是“William”?如果是“William”,这是否意味着保存第 1 行必须自动将此结果集中的所有其他行中的“Bill”更新为“William”?或者这是否意味着 save()
自动重新运行 SQL 查询以从数据库获取刷新的结果集?如果查询很耗时怎么办?
还要考虑面向对象的设计。每行都是一个单独的对象。打电话合适吗 save()
一个对象上的值是否会产生更改单独对象中的值的副作用(即使它们是同一对象集合的一部分)?这似乎是一种形式 内容耦合 大部头书。
上面的示例是一个相对简单的查询,但也允许更复杂的查询。Zend_Db 无法分析查询来区分可写结果和只读结果。这也是 MySQL 视图不可更新的原因。
其他提示
您总是可以在数据库中创建一个为您进行连接的视图。
CREATE OR REPLACE VIEW VwAction AS
SELECT [columns]
FROM action
LEFT JOIN user
ON user.id = action.user_id
然后使用
$vwAction->fetchAll();
请记住,MySQL中的视图是只读的(假设这是MySQL)
是不是创建一个视图sql表一个很好的联合解决方案? 并在一个简单的表类之后访问它
我认为如果你的逻辑在sql中比在php中更好