11

エンティティを教義で保存するには、次のようにする必要があります

$em = $this->getDoctrine()->getEntityManager();
$em->persist($product);
$em->flush();

しかし、多分私はどうにかしてそれを1行で行うことができます

$product->save();

また

$this->saveEntity($product);

また

$this->getDoctrineEntityManager()->persistAndFlush($product);

このメソッドを自分で作成する必要がある場合、symfony の方法でそれを行うにはどうすればよいですか?

4

4 に答える 4

17

まあ、独立した運用persist()flush()は全く違います。エンティティ オブジェクトを永続化すると、エンティティ マネージャにオブジェクトの変更を追跡するように指示することになります。メソッドを呼び出すとflush()、エンティティ マネージャは、エンティティ マネージャが追跡するエンティティ オブジェクトの変更を単一のトランザクションでデータベースにプッシュします。ほとんどの場合、エンティティ マネージャは複数のオブジェクトを管理する必要があります。たとえば、エンティティに加えて、追跡またはエンティティproductも必要になる場合があります。これらのエンティティ オブジェクトを保存するたびに呼び出すと、DB への複数の IO 接続が発生します。これは効率的ではありません。したがって、それらは別の操作として扱う方がよいと思います。 tagcartpersistAndFlush()

于 2012-08-18T17:58:20.657 に答える
11

フレームワーク バンドルでコントローラーを使用し、コントローラーに永続化ロジックを記述している場合はSymfony\Bundle\FrameworkBundle\Controller\Controller、次のように拡張できます。

namespace ExampleNameSpace\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

class BaseController extends Controller
{
    public function persistAndSave($entity)
    {
        $em = $this->getDoctrine()->getEntityManager();
        $em->persist($entity);
        $em->flush();
    }
}

ExampleNameSpace\Controller\BaseController他のすべてのコントローラーで、Symfony Frameworkbundle のコントローラーではなく、独自のコントローラーを拡張します。

別の方法として、私が取っているアプローチは、クラス名と注入されたドクトリン エンティティ マネージャーを持つエンティティごとにマネージャー クラスを作成することです。各マネージャー クラスは、次のメソッドを使用して抽象マネージャー クラスを拡張します。

<?php

abstract class AbstractManager
{
    /**
     * The Entity Manager
     *
     * @var \Doctrine\ORM\EntityManager  The Doctrine Entity Manager
     */
    protected $em;

    /**
     * The full class path associated with the repository
     *
     * @var string
     */
    protected $class;

    /**
     * The repository for the manager
     *
     * @var \Doctrine\ORM\EntityRepository
     */
    protected $repository;

    /**
     * Creates a new instance of the primary class managed by a given
     * manager
     *
     * @return object       A new instance of the entity being managed
     */
    public function create()
    {
        return new $this->class();
    }

    /**
     * {@inheritDoc}
     */
    public function save($object, $flush = false)
    {
        if( ! $this->supportsClass($object))
        {
            throw new \InvalidArgumentException(sprintf('Invalid entity passed to this manager, expected instance of %s', $this->class));
        }

        $this->em->persist($object);

        if($flush === true)
        {
            $this->flush();
        }

        return $object;
    }

    /**
     * {@inheritDoc}
     */
    public function delete($object, $flush = false)
    {
        if( ! $this->supportsClass($object))
        {
            throw new \InvalidArgumentException(sprintf('Invalid entity passed to this manager, expected instance of %s', $this->class));
        }

        $this->em->remove($object);

        if($flush === true)
        {
            $this->flush();
        }

        return true;
    }

    /**
     * Convenience method providing access to the entity manager flush method
     */
    public function flush()
    {
        $this->em->flush();
    }

    /**
     * {@inheritDoc}
     */
    public function supportsClass($object)
    {
        return $object instanceof $this->class || is_subclass_of($object, $this->class);
    }

    /**
     * Set class. Setter for dependency injection
     *
     * @param object $class  A class related to this manager
     */
    public function setClass($class)
    {
        $this->class = $class;
    }

    /**
     * Set entity manager. Setter for dependency injection
     *
     * @param \Doctrine\ORM\EntityManager $entity_manager
     */
    public function setEntityManager(\Doctrine\ORM\EntityManager $entity_manager)
    {
        $this->em = $entity_manager;
    }

    /**
     * Returns the repository
     *
     * @return \Doctrine\ORM\EntityRepository    A Doctrine Repository for the
     *                                          class related to this Manager
     */
    protected function getRepository()
    {
        if( ! $this->repository)
        {
            $this->repository = $this->em->getRepository($this->class);
        }

        return $this->repository;
    }
}

マネージャーは、エンティティに適切なクラスを使用して依存性注入コンテナーで構成され、担当するエンティティの作成、保存、削除、およびリポジトリへのアクセスを提供します。

次のように、マネージャを使用してコントローラにエンティティを作成します。

public function createAction(Request $request)
{
    $entityManager = $this->get('some.entity.manager');

    $entity = $entityManager->create();

    $form = $this->createForm(new EntityForm(), $entity);

    $form->bindRequest($request);

    if($form->isValid())
    {
        $entityManager->save($entity, true);
    }
}
于 2012-08-18T16:15:43.893 に答える
1

私はあなたの欲求を知っています。最初は、単一の保存方法が良さそうに見えます。

ただし、2 つの方法がある場合は、データベースに送信する前にステートメントを収集できます。それは私が推測するドクトリンの実際の作業ではありませんが、おそらく更新により、flush("together") を使用できます。このようにして、多くのオーバーヘッドを節約できます。

于 2016-02-01T00:20:03.720 に答える