web-dev-qa-db-fra.com

Comment utiliser une méthode findBy avec des critères comparatifs

J'aurais besoin d'utiliser une méthode "Find Find magique" findBy en utilisant des critères comparatifs (pas seulement des critères exacts). En d'autres termes, je dois faire quelque chose comme ceci:

$result = $purchases_repository->findBy(array("prize" => ">200"));

afin que je puisse obtenir tous les achats où le prix est supérieur à 200.

72
ElPiter

Ceci est un exemple utilisant la Expr () Class - J'en avais besoin aussi il y a quelques jours et il m'a fallu un certain temps pour découvrir quelle est la syntaxe exacte et le mode d'utilisation:

/**
 * 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();
}
29
con

La classe Doctrine\ORM\EntityRepository implémente Doctrine\Common\Collections\Selectable API.

L’interface Selectable est très flexible et nouvelle, mais elle vous permettra de gérer facilement des comparaisons et des critères plus complexes sur des référentiels et des collections uniques d’éléments, qu’il s’agisse de problèmes ORM ou ODM distincts.

Ce serait un critère de comparaison que vous venez de demander comme Doctrine ORM 2.3.2:

$criteria = new \Doctrine\Common\Collections\Criteria();
$criteria->where($criteria->expr()->gt('prize', 200));

$result = $entityRepository->matching($criteria);

Le principal avantage de cette API réside dans le fait que vous implémentez ici une sorte de modèle de stratégie qui fonctionne avec les référentiels, les collections, les collections différées et partout où l'API Selectable est implémentée.

Cela vous permet de vous débarrasser des dizaines de méthodes spéciales que vous avez écrites pour vos référentiels (comme findOneBySomethingWithParticularRule) et de vous concentrer sur l'écriture de vos propres classes de critères, chacune représentant l'un de ces filtres particuliers.

180
Ocramius

Vous devez utiliser soit DQL ou le QueryBuilder . Par exemple. dans votre achat - EntityRepository vous pouvez faire quelque chose comme ceci:

$q = $this->createQueryBuilder('p')
          ->where('p.prize > :purchasePrize')
          ->setParameter('purchasePrize', 200)
          ->getQuery();

$q->getResult();

Pour des scénarios encore plus complexes, jetez un coup d'œil à la Expr () class .

6
dbrumann
$criteria = new \Doctrine\Common\Collections\Criteria();
    $criteria->where($criteria->expr()->gt('id', 'id'))
        ->setMaxResults(1)
        ->orderBy(array("id" => $criteria::DESC));

$results = $articlesRepo->matching($criteria);
3
Patrizio Onorati

La documentation de Symfony montre maintenant explicitement comment faire ceci:

$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();

De http://symfony.com/doc/2.8/book/doctrine.html#querying-for-objects-with-dql

3
Jeff Clemens