dougu2036 2015-08-07 19:02
浏览 68
已采纳

我究竟如何在Symfony2 / Doctrine中创建自定义EntityManager?

New guy at Symfony/Doctrine. So kindly guide me.

Requirement: To create a custom EntityManager which would override some of the methods like remove (instead of remove, i want to perform an update and modify a parameter like isValid in my class, so that the records are never deleted) and a find ( find a record which has a non zero isValid ) etc and use it instead of Doctrine's EntityManager.

I started reading through this thread: Is there a way to specify Doctrine2 Entitymanager implementation class in Symfony2? and found the answer by user2563451 to be not so straightforward. I got lost when he talks about not to follow certain approaches (again no location of the files to be modified).

I have looked at the EntityManager.php and it specifically tells not to use extend the EntityManager class. Rather it asks to extend the EntityManagerDecorator. On looking at the EntityManagerDecorator, there are no methods available inside it (like create, persist, etc which I found in EntityManager) Does it mean I need to create new methods for each and every single Entity Manager functionality ?

Since there is no clear defined way to get this done, I am confused to get this thing started. Also Doctrine cookbook is of little use to me as it does not have any information to achieve this.

So any help regarding the extending of EntityManagerDecorator or EntityManager is appreciated.

Best if you can provide me step by step directions to achieve the same.

Thanks !

Edit 1: my requirement is to use my custom EntityManager instead of Doctrine's EntityManager (EM) and modify those 'remove' and 'find' methods as per my requirements. I am not sure whether I need to reuse the functionality provided by Doctrine's EM or write from scratch.

  • 写回答

2条回答 默认 最新

  • douqianbiao4216 2015-08-07 19:29
    关注

    I think you may be confusing a Manager with a Repository.

    An EntityManager is really nothing more than a Service you use to manage that specific or a collection of entities.

    A repository extends \Doctrine\ORM\EntityRepository and is what tells Doctrine how to store your entity in the database.

    You can use the combination of these two to achieve what you want.

    For example. Let's take our entity Foo

    class Foo
    {
        //...other properties
    
        protected $isValid;
    
        //...Getters and setters
    }
    

    We then have a manager for Foo.

    class FooManager
    {
        protected $class;
        protected $orm;
        protected $repo;
    
        public function __construct(ObjectManager $orm , $class)
        {
            $this->orm = $orm;
            $this->repo = $orm->getRepository($class);
    
            $metaData = $orm->getClassMetadata($class);
            $this->class = $metaData->getName();
        }
    
        public function create()
        {
            $class = $this->getClass();
            $foo = new $class;
    
            return $foo;
        }
    
        public function findBy(array $criteria)
        {
            return $this->repo->findOneBy($criteria);
        }
    
        public function refreshFoo(Foo $foo)
        {
            $this->orm->refresh($foo);
        }
    
        public function updateFoo(Foo $foo, $flush = true)
        {   
            $this->orm->persist($foo);
            if($flush)
            {
                $this->orm->flush();
            }
        }
    
        public function getClass()
        {
            return $this->class;
        }
    }
    

    We have some basic functions for Creating and Updating our object. And now if you wanted to "remove" it without actually deleting it, you can add the following function in the Manager.

    public function remove(Foo $foo)
    {
        $foo->setIsValid(false);
        return $this->update($foo);
    }
    

    This way, we update the isValid fields to false and persist it to the database. And you'd use this like any service inside your controller.

    class MyController extends Controller
    {
        public function someAction()
        {
            $fooManager = $this->get('my_foo_manager');
            $newFoo = $fooManager->create();
    
            //...
            $fooManager->remove($newFoo);
        }
    }
    

    So now we've got the remove part.

    Next, we only want to find entities that isValid set to TRUE.

    Honestly, the way I'd handle this is not even modify the find and instead in your controller

    if(!$foo->getIsValid())
    {
        //Throw some kind of error.  Or redirect to an error page.
    }
    

    But if you want to do it the other way. You can just make a repo.

    use Doctrine\ORM\EntityRepository;
    class FooRepository extends EntityRepository
    {
        public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
        {
            //Some custom doctrine query.
        }
    }
    

    We override EntityRepository's native find() function with our own.

    Finally we get all of this registered in the right places. For the manager you've got to make a service.

    services:
        my_foo_manager:
            class: AppBundle\Manager\FooManager
            arguments: [ "@doctrine.orm.entity_manager" , 'AppBundle\Entity\Foo']
    

    And for the repository, you must specify the repositoryClass in the ORM definition of your entity.

    AppBundle\Entity\Foo:
        type: entity
        repositoryClass: AppBundle\Entity\FooRepository
        table: foos
        id:
            id:
                type: integer
                generator: {strategy: AUTO}
                options: {unsigned: true}
        fields:
            isValid:
                type: boolean
    

    Knowing all of this you can now do some pretty cool things with Entities. I hope this helped. Good luck!

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 maple软件,用solve求反函数出现rootof,怎么办?
  • ¥50 汇编语言除法溢出问题
  • ¥65 C++实现删除N个数据列表共有的元素
  • ¥15 Visual Studio问题
  • ¥15 state显示变量是字符串形式,但是仍然红色,无法引用,并显示类型不匹配
  • ¥20 求一个html代码,有偿
  • ¥100 关于使用MATLAB中copularnd函数的问题
  • ¥20 在虚拟机的pycharm上
  • ¥15 jupyterthemes 设置完毕后没有效果
  • ¥15 matlab图像高斯低通滤波