Как использовать метод findBy со сравнительными критериями
Мне нужно было бы использовать метод поиска "волшебного искателя", используя сравнительные критерии (не только точные критерии). Другими словами, мне нужно сделать что-то вроде этого:
$result = $purchases_repository->findBy(array("prize" => ">200"));
Чтобы я получал все покупки, где приз превышает 200.
5 answers
Это пример использования класса Expr() - мне это тоже понадобилось несколько дней назад, и мне потребовалось некоторое время, чтобы выяснить, каков точный синтаксис и способ использования:
/**
* fetches Products that are more expansive than the given price
*
* @param int $price
* @return array
*/
public function findProductsExpensiveThan($price)
{
$em = $this->getEntityManager();
$qb = $em->createQueryBuilder();
$q = $qb->select(array('p'))
->from('YourProductBundle:Product', 'p')
->where(
$qb->expr()->gt('p.price', $price)
)
->orderBy('p.price', 'DESC')
->getQuery();
return $q->getResult();
}
Класс Doctrine\ORM\EntityRepository
орудия Doctrine\Common\Collections\Selectable
API.
Интерфейс Selectable
очень гибкий и довольно новый, но он позволит вам легко обрабатывать сравнения и более сложные критерии как в репозиториях, так и в отдельных коллекциях элементов, независимо от того, в ORM или ODM или полностью отдельных проблемах.
Это будет критерием сравнения, как вы только что просили, как в доктрине ORM 2.3.2
:
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->gt('prize', 200));
$result = $entityRepository->matching($criteria);
Основным преимуществом этого API является то, что вы здесь реализован какой-то шаблон стратегии, и он работает с репозиториями, коллекциями, отложенными коллекциями и везде, где реализован API Selectable
.
Это позволяет вам избавиться от десятков специальных методов, которые вы написали для своих репозиториев (например, findOneBySomethingWithParticularRule
), и вместо этого сосредоточиться на написании собственных классов критериев, каждый из которых представляет один из этих конкретных фильтров.
Вы должны использовать либо DQL, либо QueryBuilder. Например, в вашей покупке-EntityRepository вы могли бы сделать что-то вроде этого:
$q = $this->createQueryBuilder('p')
->where('p.prize > :purchasePrize')
->setParameter('purchasePrize', 200)
->getQuery();
$q->getResult();
Для еще более сложных сценариев взгляните на класс Expr().
Документация Symfony теперь явно показывает, как это сделать:
$em = $this->getDoctrine()->getManager();
$query = $em->createQuery(
'SELECT p
FROM AppBundle:Product p
WHERE p.price > :price
ORDER BY p.price ASC'
)->setParameter('price', '19.99');
$products = $query->getResult();
Из http://symfony.com/doc/2.8/book/doctrine.html#querying-for-objects-with-dql
$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->gt('id', 'id'))
->setMaxResults(1)
->orderBy(array("id" => $criteria::DESC));
$results = $articlesRepo->matching($criteria);