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