Symfony 应用程序 - 如何将计算字段添加到 Propel 对象?

2024-03-28

处理 Propel 对象的计算字段的最佳方式是什么?

假设我有一个对象“Customer”,它有一个相应的表“customers”,并且每一列对应于我的对象的一个​​属性。我想做的是:在视图 A 上使用它时,向我的对象添加一个计算属性“已完成订单数”,但不在视图 B 和 C 上使用它。

计算出的属性是通过 ID 链接到我的“客户”对象的“订单”对象的 COUNT() 个。

我现在可以做的是首先选择所有 Customer 对象,然后迭代计算所有这些对象的 Orders,但我认为在单个查询中执行此操作会提高性能。但我无法正确“水合”我的 Propel 对象,因为它不包含计算字段的定义。

你会如何处理它?


有几种选择。首先,是在数据库中创建一个视图来为您进行计数,类似于我的答案here https://stackoverflow.com/questions/234785/#235267。我为当前正在从事的 Symfony 项目执行此操作,其中给定表的只读属性实际上比表本身宽得多。这是我的建议,因为分组列(max()、count() 等)无论如何都是只读的。

其他选项是将此功能实际构建到您的模型中。您绝对可以自己进行补水,但有点复杂。这是粗略的步骤

  1. 将列添加到您的Table类作为受保护的数据成员。
  2. 为这些列编写适当的 getter 和 setter
  3. 覆盖水合物方法并在其中使用其他查询的数据填充新列。确保在第一行调用parent::Hydrate()

但是,这并不比您已经谈论的好多少。你仍然需要N+ 1 个查询来检索单个记录集。但是,您可以在步骤#3 中发挥创意,以便N是计算的列数,而不是返回的行数。

另一种选择是在您的系统上创建自定义选择方法Table同侪阶级。

  1. 执行上面的步骤 1 和 2。
  2. 编写您将通过 Propel::getConnection() 过程手动查询的自定义 SQL。
  3. 通过迭代结果集手动创建数据集,并在此时处理自定义水合,以免在 doSelect 进程使用时破坏水合。

这是此方法的一个示例

<?php

class TablePeer extends BaseTablePeer
{
    public static function selectWithCalculatedColumns()
    {
        //  Do our custom selection, still using propel's column data constants
        $sql = "
            SELECT " . implode( ', ', self::getFieldNames( BasePeer::TYPE_COLNAME ) ) . "
                 , count(" . JoinedTablePeer::ID . ") AS calc_col
              FROM " . self::TABLE_NAME . "
              LEFT JOIN " . JoinedTablePeer::TABLE_NAME . "
                ON " . JoinedTablePeer::ID . " = " . self::FKEY_COLUMN
        ;

        //  Get the result set
        $conn   = Propel::getConnection();
        $stmt   = $conn->prepareStatement( $sql );
        $rs = $stmt->executeQuery( array(), ResultSet::FETCHMODE_NUM );

        //  Create an empty rowset
        $rowset = array();

        //  Iterate over the result set
        while ( $rs->next() )
        {
            //  Create each row individually
            $row = new Table();
            $startcol = $row->hydrate( $rs );

            //  Use our custom setter to populate the new column
            $row->setCalcCol( $row->get( $startcol ) );
            $rowset[] = $row;
        }
        return $rowset;
    }
}

您的问题可能还有其他解决方案,但超出了我的知识范围。祝你好运!

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Symfony 应用程序 - 如何将计算字段添加到 Propel 对象? 的相关文章

随机推荐