更好的推进查询


A better Propel query

>我有4个表:

  1. branches(包含分支信息)
  2. offered_class_types(每个分支都有一组可用的类)
  3. class_sessions(每种课程类型都有自己的课程,如白天、晚上和晚上)
  4. class_dates(每个日期对应一个会话)

所以我的流程:每个日期对应于一个会话(通过直接链接两者的代码),该会话对应于两个东西的类型 1. 分支 ID 和 2. 类名(分支可以提供可以具有相同会话的相同类类型)。每个类类型都使用与会话表对应的相同分支 ID 对应于分支表。

我想将此代码转换为一个查询,而不是现在的两个查询。在切换到 Propel 之前,它是在单个查询中。

$class = ClassDatesQuery::create()->findPk(160);
$classSession = $class->getOfferedSessionsRelatedByCode();
$classType = OfferedClassTypesQuery::create()
   ->filterByType($classSession->getClassname())
   ->filterByBranchid($classSession->getBranchid())
   ->find();

一个简单的查询,类似于下面的查询,如果你在两个表之间有一个简单的关系,就会浮出水面:

$classType = OfferedClassTypesQuery::create()
  ->useClassDatesQuery()
    ->filterByPk(160)
  ->endUse()
  ->filterByXXX(YYY)
  ...
  ->find();

复杂之处在于您有多个联接条件,并且在查询之前这些条件是未知的。

对此,至少有两 (2) 种替代方法。

选项一

编写原始 SQL 查询,并针对数据库连接运行它,然后使用适当的对象/类包装器手动冻结结果集,如下所示:

$db = Propel::getConnection();
$sql = 'SELECT OfferedClassTypes.* FROM ...';
$query = $db->prepare($sql);
$formatter = new PropelObjectFormatter();
// Here you specify the class that matches
// the expected results set
$formatter->setClass('OfferedClassTypes');
$classType = $formatter->format($query);

请注意 OfferedClassTypes.* ,因为您只需要该表中的列,以便可以通过匹配的对象进行水合

选项二

将原始 SQL 查询放入视图中,引用:

推动视图表的自定义 sql

因此,您可能会像这样定义视图:

CREATE VIEW ViewOfferedClassTypes AS
  SELECT
    ClassDates.ID as ClassDateID,
    OfferedClassTypes.*
    ...

然后在您的架构中,您将拥有:

<table
  name="ViewOfferedClassTypes"
  phpName="ViewOfferedClassTypes"
  readOnly="true"
  skipSql="true">
  <!-- More columns from the OfferedClassTypes table -->
  <column name="ClassDateID" ... /><!-- From ClassDates table -->
</table>

请注意ClassDateID列,以便您可以在筛选器中使用:

$classType = ViewOfferedClassTypesQuery::create()
  ->filterByClassDateID(160)
  ->find();
选项

1 快速而肮脏,而选项 2 更精致但更干净/更有条理。

我希望这有帮助,祝你好运。