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 コメント:
コメントを投稿