リポジトリを使う場合。
$this->getDoctrine()->getRepository()を使う
1 2 3 |
$product = $this->getDoctrine() ->getRepository('AcmeStoreBundle:Product') ->find($id); |
いろいろなfindメソッドが用意されている。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
$repository = $this->getDoctrine() ->getRepository('AcmeStoreBundle:Product'); // プライマリーキー(通常は"id")でクエリ $product = $repository->find($id); // あるカラム値に基づいて find する、動的なメソッド名 $product = $repository->findOneById($id); $product = $repository->findOneByName('foo'); // // *すべて* の商品を find $products = $repository->findAll(); // 任意のカラム値に基づく、商品群の find $products = $repository->findByPrice(19.99); |
複数条件もいけます。
1 2 3 4 5 6 7 8 |
// name と price の両方にマッチする1つの商品を取得するクエリ $product = $repository->findOneBy(array('name' => 'foo', 'price' => 19.99)); // name にマッチするすべての商品を price 順で取得するクエリ $product = $repository->findBy( array('name' => 'foo'), array('price' => 'ASC') ); |
DQLを使う場合
1 2 3 4 5 6 |
$em = $this->getDoctrine()->getEntityManager(); $query = $em->createQuery( 'SELECT p FROM AcmeStoreBundle:Product p WHERE p.price > :price ORDER BY p.price ASC' )->setParameter('price', '19.99'); $products = $query->getResult(); |
結果が1つと分かっていればgetResult()の代わりにgetSingleResult()が使える。
1 |
$product = $query->getSingleResult(); |
注意事項
getSingleResult() メソッドは、結果がない場合、一つより多くの結果が返ってきたときに、それぞれ、Doctrine\ORM\NoResultException、Doctrine\ORM\NonUniqueResultException をスローします。もしこのメソッドを使用する場合は(そして、1つより多くの結果を返すようなクエリを実行している場合は)、try-catch ブ ロックで囲って、ただひとつの結果が返ることを明確にしておかなければなりません。
1 2 3 4 5 6 7 8 |
$query = $em->createQuery('SELECT ....') ->setMaxResults(1); try { $product = $query->getSingleResult(); } catch (\Doctrine\Orm\NoResultException $e) { $product = null; } |
パラメータのセット
setParameter() メソッドに注目してください。Doctrine を使用する際は、先の例のように、外部的な値は常に”プレースホルダ”として設定するのが良いでしょう。
1 |
... WHERE p.price > :price ... |
プレースホルダ price に値をセットするには、setParameter() メソッドを呼びます。
1 |
->setParameter('price', '19.99') |
値を直に置くのではなくパラメータを使用するのは、SQL インジェクションを防ぐためであり、常にそうすべきです。複数のパラメータがある時は、setParameters() メソッドを使用すれば一度に値をセット出来ます。
1 2 3 4 |
->setParameters(array( 'price' => '19.99', 'name' => 'Foo', )) |
3. QueryBuilderを使う
1 2 3 4 5 6 7 8 9 10 |
$repository = $this->getDoctrine() ->getRepository('AcmeStoreBundle:Product'); $query = $repository->createQueryBuilder('p') ->where('p.price > :price') ->setParameter('price', '19.99') ->orderBy('p.price', 'ASC') ->getQuery(); $products = $query->getResult(); |