【问题标题】:Symfony Propel criteriaSymfony 推进标准
【发布时间】:2009-01-19 11:18:02
【问题描述】:

有没有办法将 MySQL 对象转换为条件对象?我试过这个查询:

select 
  p.disrepid, 
  p.subject, p.body, 
  c.disrepid as disrepid1, 
  c.subject as subject1, 
  c.body as body1 
from discusreply as p, discusreply as c 
where p.distopid=' . $this->id . ' 
  and (c.disrepid = p.parentid or c.parentid = p.distopid) 
order by p.disrepid ASC

我尝试了很多将此查询转换为Criteria,但没有任何反应。我想要这个标准对象将它传递给 Pager 类以完成分页。 $pager->setCriteria($c);.

【问题讨论】:

    标签: mysql symfony1 criteria propel


    【解决方案1】:

    您可以使用自己的 SQL 执行查询,但没有自动方式将 sql 转换为 Criteria 对象。

    $con = Propel::getConnection(DATABASE_NAME);
    $sql = "SELECT books.* FROM books 
        WHERE NOT EXISTS (SELECT id FROM review WHERE book_id = book.id)";
    $stmt = $con->createStatement();
    $rs = $stmt->executeQuery($sql, ResultSet::FETCHMODE_NUM);
    $books = BookPeer::populateObjects($rs);
    

    这会一起绕过 Criterion 对象。您提到想要一个标准对象,以便您可以将其输入寻呼机。您可以改为在寻呼机中设置自定义选择方法,然后该寻呼机将执行您的自定义查询。如果您需要向其中传递参数,我建议使用您自己的寻呼机类扩展 sfPropel,该类可以选择将参数传递给您的对等选择方法,因此您根本不必使用 Criteria 对象。作为一种快速的替代方法,您可以执行以下操作,将您的 Criteria 用作您选择参数的容器:

    $c = new Criteria();
    $c->add(DiscussreplyPeer::ID, $myId);
    $pager = new sfPropelPager();
    $pager->setCriteria($c);
    $pager->setPeerMethod('getReplies');
    

    然后在你的同龄人中:

    public static function getReplies(Criteria $c) {
        $map = $c->getMap();
        $replyId = $map[DiscussreplyPeer::ID]->getValue();
    
        $con = Propel::getConnection(DATABASE_NAME);
        $sql = "select p.disrepid, p.subject, p.body, c.disrepid as disrepid1, c.subject as subject1, c.body as body1 from discusreply as p, discusreply as c where p.distopid=? and (c.disrepid = p.parentid or c.parentid = p.distopid) order by p.disrepid ASC";
    
        $stmt = $con->prepareStatement($sql);
        $stmt->setString(1, $replyId);
    
        $rs = $stmt->executeQuery();
    
        $results = array();
        while ($rs->next()) {
          // for example
            $results['disrepid'] = $rs->getInt('disrepid');
        }
    
        return $results;
    }
    

    有关 propel 和 symfony 的更多提示可以在以下位置找到: http://stereointeractive.com/blog/2007/06/12/propel-queries-using-custom-sql-peer-classes-and-criterion-objects/

    【讨论】:

      【解决方案2】:

      This site 对学习编写标准有很大帮助 - 您可以使用它从伪 SQL 生成标准代码。我还建议抓住Symfony/Propel cheat sheets

      特别是对于您的查询,您将需要这样的内容:

      $c = new Criteria();
      $c->addJoin(discusreply::DISREPID, discusreply::PARENTID, Criteria::INNER_JOIN);  
      $c->clearSelectColumns();
      $c->addSelectColumn(discusreplyPeer::Disrepid); 
      ...
      $c->add(discusreplyPeer::DISTOPID, $this->id, Criteria::EQUAL);
      ... 
      $c->addAscendingOrderByColumn(discusreply::DISREPID);
      

      我不确定 Criteria 系统是否支持内部连接的多个子句,因此您可能必须为该查询恢复到 ad-hoc SQL(如果可以的话,我很想知道如何)。以下代码将创建一个 ResultSet 对象,类似于您从简单的数据库抽象层获得的对象。

      $sql = "SELECT ...";
      $dbh = Propel::getConnection([DB]);
      $sth = $dbh->createStatement();
      $res = $sth->executeQuery($sql, ResultSet::FETCHMODE_NUM);
      

      我认为在这样的查询上使用 ad-hoc 方法没有什么缺点,因为当您只返回特定列时,您将不得不处理 ResultSet 对象而不是特定于表的对象。

      【讨论】:

      • 我发现您可以执行类似 $c->addJoin(TABLE_A::ID, TABLE_B::ID.' AND '.TABLE_B::VALUE.' > 0', Criteria::LEFT_JOIN) 之类的操作; (使用推进 1.2,而不是 1.3)向连接添加多个条件。
      【解决方案3】:

      您可以尝试使用 this site 从 sql 自动生成条件。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多