在Symfony2 / Doctrine中如何创建自定义EntityManager? [英] How exactly do I create a custom EntityManager in Symfony2/Doctrine?

查看:185
本文介绍了在Symfony2 / Doctrine中如何创建自定义EntityManager?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Symfony / Doctrine的新人。好好指导我



要求:要创建一个自定义EntityManager,它将覆盖某些方法,如remove(而不是删除),我想执行更新并修改参数,如isValid在我的类,所以记录永远不会被删除)和find(找到一个非零的记录isValid)等等,而不是使用Doctrine的EntityManager。



我开始阅读此线程:
有没有办法在Symfony2中指定Doctrine2 Entitymanager实现类?,并发现user2563451的答案并不那么简单。当他谈到不遵循某些方法(再次没有要修改的文件的位置)时,我迷路了。



我看过EntityManager.php,它具体告诉不要使用扩展EntityManager类。而是要求扩展EntityManagerDecorator。在查看EntityManagerDecorator时,它内部没有可用的方法(如在EntityManager中发现的创建,持久化等)这是否意味着我需要为每个实体管理器功能创建新的方法?



由于没有明确的定义方式来完成此操作,我感到困惑,让这个事情开始了。此外,Doctrine cookbook对我来说没有什么用,因为它没有任何信息来实现这一点。



所以关于扩展EntityManagerDecorator或EntityManager的任何帮助都是值得赞赏的。



如果您能提供我一步一步的指导,以达到相同的效果,最好。



谢谢! >

编辑1:我的要求是使用我的自定义EntityManager而不是Doctrine的EntityManager(EM),并按照我的要求修改这些删除和查找方法。我不知道我是否需要重用Doctrine的EM提供的功能或从头开始写。

解决方案

我想你可能会将Manager与存储库混淆。



一个EntityManager真的只是一个用于管理该特定或一组实体的服务。



一个存储库扩展了 \Doctrine\ORM\EntityRepository ,是什么告诉Doctrine如何将您的实体存储在数据库中。



您可以使用这两者的组合来实现您想要的。



例如。让我们把我们的实体Foo

  class Foo 
{
//...other properties

protected $ isValid;

//...Getters and setter
}

我们有一个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;
}
}

我们有一些基本的功能,用于创建和更新我们的对象。而现在,如果您想删除它,而不实际删除它,您可以在管理器中添加以下功能。

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

这样,我们更新了 isValid 字段为false并将其保存到数据库。而您可以像控制器中的任何服务一样使用。

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

// ...
$ fooManager-> remove($ newFoo);
}
}

所以现在我们有了删除部分。



接下来,我们只想找到 isValid 设置为TRUE的实体。



老实说,我处理这个的方式甚至不会修改find​​,而不是在你的控制器中

  if(!$ foo> getIsValid())
{
//抛出某种错误。或重定向到错误页面。
}

但是,如果你想要这样做。你可以做一个回购。

 使用Doctrine\ORM\EntityRepository; 
class FooRepository扩展EntityRepository
{
public function find($ id,$ lockMode = LockMode :: NONE,$ lockVersion = null)
{
//某些自定义原则查询
}
}

我们用自己的覆盖EntityRepository的本机find()函数。



最后,我们将所有注册在正确的地方。对于经理,你必须提供服务。

 服务:
my_foo_manager:
类: AppBundle\Manager\FooManager
参数:[@ doctrine.orm.entity_manager,'AppBundle\Entity\Foo']

对于存储库,您必须在实体的ORM定义中指定 repositoryClass

  AppBundle\Entity\Foo:
type:entity
repositoryClass:AppBundle\Entity\FooRepository
table :foos
id:
id:
类型:整数
生成器:{策略:AUTO}
选项:{unsigned:true}
fields:
isValid:
type:boolean

了解所有这些,你现在可以做一些与实体相当酷的事情。我希望这有帮助。祝你好运!


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.

解决方案

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!

这篇关于在Symfony2 / Doctrine中如何创建自定义EntityManager?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆