代码之家  ›  专栏  ›  技术社区  ›  Aron Rotteveel

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

  •  7
  • Aron Rotteveel  · 技术社区  · 16 年前

    情况如下:我有两个模型:“Action”和“User”。这些模型分别引用“操作”和“用户”表。

    我的操作表包含一列 user_id . 现在,我需要对所有操作以及分配给它们的用户进行概述。当我使用 $action->fetchAll() ,我只有用户ID,因此我希望能够加入来自用户模型的数据,最好不用调用 findDependentRowset() .

    我想创造一种习惯 fetchAll() , fetchRow() find() 方法,但这将打破默认行为。

    解决这个问题的最好办法是什么?任何帮助都将不胜感激。

    3 回复  |  直到 9 年前
        1
  •  14
  •   Bill Karwin    16 年前

    我在Zend框架中设计并实现了表关系特性。

    我的第一个评论是,你不会使用 findDependentRowset() 不管怎样,你会用 findParentRow() 如果操作具有对用户的外键引用。

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

    编辑: save() 在物体上。

    您还可以使用Zend_Db_Table_Select类(在我离开项目后实现)根据操作和用户之间的连接检索行集。

    $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());
    }
    

    请注意,这种基于联接查询的行集是只读的。不能在行对象中设置字段值并调用 保存()

    编辑:

    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的行,我更改来自用户对象的一个字段:

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

    是否自动重新运行SQL查询以从数据库获取刷新的结果集?如果查询很耗时怎么办?

    还考虑面向对象的设计。每一行都是一个单独的对象。打电话合适吗 在一个对象上更改单独对象中的值会产生副作用(即使它们是同一对象集合的一部分)?这似乎是一种 Content Coupling

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

        2
  •  2
  •   Peter Bailey    16 年前

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

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

    $vwAction->fetchAll();
    

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

        3
  •  1
  •   dave    15 年前

    并在一个简单的表类之后访问它

    我认为,如果您的逻辑是sql而不是php,那就更好了