Критерии Symfony Propel - PullRequest
       14

Критерии Symfony Propel

1 голос
/ 19 января 2009

Есть ли какой-нибудь возможный способ преобразовать объект 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);.

Ответы [ 3 ]

6 голосов
/ 07 августа 2009

Вы можете использовать свой собственный 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. В качестве быстрой альтернативы вы можете сделать что-то подобное, используя ваши критерии в качестве контейнера для выбранных параметров:

$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 голосов
/ 31 января 2009

Вы можете попробовать автоматически сгенерировать критерии из sql, используя этот сайт .

2 голосов
/ 19 января 2009

Этот сайт очень поможет в обучении написанию критериев - вы можете использовать его для генерации кода критериев из псевдо-SQL. Я также рекомендовал бы захватить шпаргалки Symfony / Propel .

В частности, для вашего запроса вам понадобится что-то вроде этого:

$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 поддерживает несколько предложений для внутреннего объединения, поэтому вам, возможно, придется вернуться к специальному SQL для этого запроса (если это произойдет, я хотел бы знать, как). Следующий код создаст объект ResultSet, аналогичный тому, который вы получили бы из простых слоев абстракции базы данных.

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

Я не думаю, что есть большой недостаток в использовании специального метода в таком запросе, так как вам придется иметь дело с объектами ResultSet, а не с объектами таблицы, когда вы возвращаете только определенные столбцы.

...