こんにちわ、今回からは、Symfony2にデフォルトで付属しているORMであるDoctrine2の小ネタを紹介したいと思います。半分は備忘録になります
今日は、一度に多数のデータを挿入したいときはどうするの?です。基本的な使い方は
http://docs.symfony.gr.jp/symfony2/book/doctrine.htmlを参照してください。
エンティティ
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | use Doctrine\ORM\Mapping as ORM; /** * @ORM\Entity * @ORM\Table(name="product") */ class Product { /** * @ORM\Id * @ORM\Column(type="integer") * @ORM\GeneratedValue(strategy="AUTO") */ protected $id ; /** * @ORM\Column(type="string", length=100) */ protected $name ; /** * @ORM\Column(type="decimal", scale=2) */ protected $price ; /** * @ORM\Column(type="text") */ protected $description ; } |
公式ページのまま利用しています。
こちらを普通にInsertするときは
単独Insert
1 2 3 4 5 6 7 8 9 10 11 12 13 | public function createAction() { $product = new Product(); $product ->setName( 'A Foo Bar' ); $product ->setPrice( '19.99' ); $product ->setDescription( 'Lorem ipsum dolor' ); $em = $this ->getDoctrine()->getEntityManager(); $em ->persist( $product ); $em -> flush (); return new Response( 'Created product' ); } |
です、では、複数個のProductを同時にInsertする場合はどうすればよいでしょう。
ポイントは、Doctrine2のエンティティマネージャーは
- persistでは、オブジェクトを管理下におくだけ
- flushで管理しているオブジェクトに対応した、SQL文を発行する
という点です、これに従って書いてみましょう
複数Insert
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | public function createManyAction() { $em = $this ->getDoctrine()->getEntityManager(); $names = Array( "a" , "b" ); $prices = Array(100, 200); $descriptions = Array( "hello" , "goodbye" ); for ( $i = 0; $i < 2; $i ++){ $product = new Product(); $product ->setName( $names [ $i ]); $product ->setPrice( $prices [ $i ]); $product ->setDescription( $descriptions [ $i ]); $em ->persist( $product ); } $em -> flush (); return new Response( 'Created products' ); } |
となります。persistにはPDOでいうprepareの役割もあるので、この方法だとクエリーキャッシュを有効に利用できるそうです。http://doctrine-orm.readthedocs.org/en/latest/reference/batch-processing.html?highlight=batchなどが参考になるでしょうか。
一気にInsertするのではなく、forの中でInsertを実行したい場合、以下のようになります
複数Insert1回ごと
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | public function createManyAction() { $em = $this ->getDoctrine()->getEntityManager(); $names = Array( "a" , "b" ); $prices = Array(100, 200); $descriptions = Array( "hello" , "goodbye" ); for ( $i = 0; $i < 2; $i ++){ $product = new Product(); $product ->setName( $names [ $i ]); $product ->setPrice( $prices [ $i ]); $product ->setDescription( $descriptions [ $i ]); $em ->persist( $product ); $em -> flush (); $em ->clear(); } return new Response( 'Created products' ); } |
SQLを発行するたびに、管理するオブジェクトをクリアしている点がポイントです。
今回はこれで失礼いたします。
投稿者プロフィール
-
中の人には主に、
PHP・Symfony2系の人と
Ruby・Rails系の人がいます。
ときどきJavascript・データベースにも手を出すかもしれません。
最新の投稿
データベース2015年2月3日Symfony2 Doctrine2の小ネタ(OneToMany,ManyToOneリレーション)
データベース2015年1月28日Symfony2 Doctrine2の小ネタ(OneToOneリレーション)
開発2015年1月21日Symfony2でもデザインパターン(PHPクラス編)
開発2014年11月26日Google検索結果画面にパンくずリストを表示する方法 (リッチスニペット対応)