Model (Doctrine) について① の続きです。
詳しくは、Databases and Doctrine ("The Model")を参照してください。
オブジェクトの永続化
INSERTするときは以下のように、Entityに値をセットし、EntituManagerのpersist()を呼び、最後にflush() を実行すれば良い。
use Acme\StoreBundle\Entity\Product; use Symfony\Component\HttpFoundation\Response; public function createAction() { // Productインスタンスの作成 $product = new Product(); // 値をセット $product->setName('A Foo Bar'); $product->setPrice('19.99'); $product->setDescription('Lorem ipsum dolor'); // EntityManager オブジェクトの取得 $em = $this->getDoctrine()->getEntityManager(); // データの保存 $em->persist($product); $em->flush(); return new Response('Created product id '.$product->getId()); }
オブジェクトのフェッチ
Doctrineオブジェクトからフェッチ対象のリポジトリを取得 (getRepository) する。
そのリポジトリオブジェクトに対し、 find, findAll, findBy などでデータを取得できる。
$product = $this->getDoctrine() ->getRepository('AcmeStoreBundle:Product') ->find($id);
いろんな取得方法がある。
// IDからデータを取得 $product = $repository->find($id); // 指定したカラムの値からデータを1つ取得 $product = $repository->findOneById($id); $product = $repository->findOneByName('foo'); // 同様に、指定したカラムの値からデータを取得 (複数) $products = $repository->findByPrice(19.99); // 細かい検索条件を付ける場合は以下 (findOneByは1つ、findByは複数取得) $product = $repository->findOneBy(array('name' => 'foo', 'price' => 19.99)); $product = $repository->findBy( array('name' => 'foo'), array('price' => 'ASC') ); // 全て取得 $products = $repository->findAll(); // 自分でクエリーを生成することも簡単 $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(); // クエリービルダーを使用することもできる (createQueryBuilder) $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();
オブジェクトのアップデートと削除
データをアップデート処理と削除処理について。
ちなみに、update, delete, どちらも最後に flush() を呼ぶ必要があります。
public function updateAction($id) { // データを取得 $em = $this->getDoctrine()->getEntityManager(); $product = $em->getRepository('AcmeStoreBundle:Product')->find($id); if (!$product) { throw $this->createNotFoundException('No product found for id '.$id); } // データに値をセット $product->setName('New product name!'); // データを更新 // $productの中身を変更して、そのまま flush() すれば更新される。(参照渡しでエンティティを取得しているっぽいね。) // よって、persist() とかいちいち呼ぶ必要が無いです。 $em->flush(); // 削除はこうやる $em->remove($product); $em->flush(); return $this->redirect($this->generateUrl('homepage')); }
カスタムなリポジトリクラスの作成
前述のように、自分でクエリーを作成 (createQuery) する場合を考える。そのとき、毎回同じコードをコントローラに記述する事になってしまうと煩雑になってしまう。そんなときは、自分でカスタムなリポジトリクラスを作成することで解決できる。
まず、ProductRepository を使いますよーと、アノテーションで記載する。
// src/Acme/StoreBundle/Entity/Product.php namespace Acme\StoreBundle\Entity; use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity(repositoryClass="Acme\StoreBundle\Repository\ProductRepository") */ class Product { //... }
....で、以下のコマンドを実行する
php app/console doctrine:generate:entities Acme
そうすると、リポジトリクラスが作成される(以下)
そこにfindAllOrderedByNameなどのカスタムなプログラムを書いてやる。これでOK。
// src/Acme/StoreBundle/Repository/ProductRepository.php namespace Acme\StoreBundle\Repository; use Doctrine\ORM\EntityRepository; class ProductRepository extends EntityRepository { public function findAllOrderedByName() { return $this->getEntityManager() ->createQuery('SELECT p FROM AcmeStoreBundle:Product p ORDER BY p.name ASC') ->getResult(); } }
0 コメント:
コメントを投稿