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