Symfony / Doctrine的新人。亲切地指导我。
要求:要创建一个自定义的EntityManager,它将覆盖某些方法,例如remove(而不是remove,我想执行更新并修改类中的isValid之类的参数,以便永远不会删除记录)和find(找到一个非零isValid的记录)等,并使用它而不是Doctrine的EntityManager。
我开始阅读这个帖子: Is there a way to specify Doctrine2 Entitymanager implementation class in Symfony2?并且发现user2563451的答案并不那么简单。当他谈到不遵循某些方法时,我迷路了(再次没有要修改的文件的位置)。
我查看了EntityManager.php,它特别指出不要使用扩展EntityManager类。而是要求扩展EntityManagerDecorator。在查看EntityManagerDecorator时,其中没有可用的方法(比如我在EntityManager中找到的create,persist等)这是否意味着我需要为每个Entity Manager功能创建新方法?
由于没有明确的方法来完成这项工作,我很困惑,让这件事情开始了。另外,Doctrine cookbook对我来说没有什么用处,因为它没有任何信息可以达到这个目的。
因此,有关扩展EntityManagerDecorator或EntityManager的任何帮助都表示赞赏。
如果你能为我提供一步一步的指导,那就最好了。
谢谢!
编辑1:我的要求是使用我的自定义EntityManager而不是Doctrine的EntityManager(EM),并根据我的要求修改那些'remove'和'find'方法。我不确定是否需要重用Doctrine EM提供的功能或从头开始编写。
答案 0 :(得分:4)
我认为您可能会将Manager与存储库混淆。
EntityManager实际上只是用于管理特定实体或实体集合的服务。
存储库扩展\Doctrine\ORM\EntityRepository
,它告诉Doctrine如何将您的实体存储在数据库中。
您可以结合使用这两者来实现您的目标。
例如。我们来看看我们的实体Foo
class Foo
{
//...other properties
protected $isValid;
//...Getters and setters
}
然后我们有一位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;
}
}
我们有一些用于创建和更新对象的基本功能。现在,如果您想要“删除”它而不实际删除它,您可以在Manager中添加以下功能。
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的实体。
老实说,我处理这个的方式甚至不是修改查找而是在你的控制器中
if(!$foo->getIsValid())
{
//Throw some kind of error. Or redirect to an error page.
}
但如果你想以另一种方式去做。你可以做一个回购。
use Doctrine\ORM\EntityRepository;
class FooRepository extends EntityRepository
{
public function find($id, $lockMode = LockMode::NONE, $lockVersion = null)
{
//Some custom doctrine query.
}
}
我们使用自己的。(/ p>)覆盖EntityRepository的本机find()函数
最后,我们将所有这些都注册在正确的位置。对于经理你必须提供服务。
services:
my_foo_manager:
class: AppBundle\Manager\FooManager
arguments: [ "@doctrine.orm.entity_manager" , 'AppBundle\Entity\Foo']
对于存储库,您必须在实体的ORM定义中指定repositoryClass
。
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
了解所有这些,您现在可以使用实体做一些非常酷的事情。我希望这有帮助。祝你好运!
答案 1 :(得分:0)
关于您的用例,您应该使用Doctrine Lifecycle Callbacks作为删除案例,并简单地在实体存储库中使用find方法。