Я пытаюсь построить запрос динамически. Это начальное состояние в порядке. Это начальное условие where, которое должно присутствовать в каждом запросе
$qb->add('where', $qb->expr()->andx(
$qb->expr()->eq('s.competitor', $competitor),
$qb->expr()->eq('s.ignored', $ignored),
$qb->expr()->eq('s.id', $params['s_id']),
$qb->expr()->eq('s.id', 'k.targetSite')
), true);
Но приложение, которое я создаю, позволяет пользователям фильтровать. Когда это произойдет, я хочу добавить дополнительные предложения where в мой конструктор запросов. Когда эта строка выполняется позже в коде, она перезаписывает вышеприведенный оператор where.
$qb->add('where', $qb->expr()->like($col, $val), true );
Из того, что я прочитал, третий параметр $append
должен сохранить предыдущие утверждения, но этого не происходит. В Doctrine 1.2 я мог бы просто сделать что-то вроде этого:
foreach($filter as $col => $val) {
$dql->addWhere($col = ?, array($val));
}
Как динамически добавлять предложения where в мой QueryBuilder?
Обновление
Вот полное изложение
$where = array('col' => 'k.text', 'val' => 'some word%');
$qb = $this->entityManager->createQueryBuilder()
->select('s, sc')
->from('Dashboard\Entity\Section', 'sc')
->innerJoin('sc.keyword', 'k')
->innerJoin('sc.site', 's')
->leftJoin('k.keywordCategory', 'kc')
->leftJoin('k.keywordSubCategory', 'ksc');
$qb->add('where', $qb->expr()->andx(
$qb->expr()->eq('s.competitor', $competitor),
$qb->expr()->eq('s.ignored', $ignored),
$qb->expr()->eq('s.id', $params['s_id']),
$qb->expr()->eq('s.id', 'k.targetSite')
), true);
if ($where) {
$qb->add('where', $qb->expr()->andx(
$qb->expr()->like($where['col'], $where['val'])
), true);
}
$qb->addGroupBy('k.id');
$qb->addGroupBy('s.id');
$qb->setFirstResult( $params['start'] )
->setMaxResults( $params['limit'] );
$q = $qb->getQuery();
echo $q->getSql();
А на выходе
SELECT s0_.id AS id0, k1_.id AS id1, k1_.name AS name2, k2_.id AS id3, k2_.name AS name4, k3_.id AS id5, k3_.text AS text6, k3_.search_vol AS search_vol7, s4_.id AS id8, s4_.sub_domain AS sub_domain9, MIN(s0_.rank) AS sclr10, MAX(s0_.created) AS sclr11
FROM section s0_
INNER JOIN keyword k3_ ON s0_.k_id = k3_.id
INNER JOIN site s4_ ON s0_.s_id = s4_.id
LEFT JOIN keyword_category k1_ ON k3_.k_cat_id = k1_.id
LEFT JOIN keyword_sub_category k2_ ON k3_.k_subcat_id = k2_.id
WHERE k3_.text LIKE 'some word%'
GROUP BY k3_.id, s4_.id LIMIT 25 OFFSET 0
Если я не добавлю в это предложение if ($where)
, то первые andx
, где операторы все еще на месте. Но когда я пытаюсь динамически добавить их, добавляется только последний оператор WHERE, все остальные очищаются. Я должен также добавить, что я тоже так пробовал.
if ($where) {
$qb->add('where', $qb->expr()->like($where['col'], $where['val']), true);
}
Я могу успешно использовать
$qb->andWhere( $qb->expr()->like($where['col'], $where['val']) );
Но документы API для Query Builder указывают, как я пытаюсь их использовать, также должно быть допустимо. Хотел убедиться, что я все делал правильно, или это была ошибка.