让我们看看我的建筑师:
型号:
// links table: (ID, LINKNAME)
Class Link extends Link_base
{
}
控制器:
public function index()
{
$this->links = new Doctrine - here I build the query, SELECT, ORDER BY, etc
}
在这个例子中,模型可以保持为空(没有严重的逻辑),我只需要一个带有顺序的选择。我不确定我是否可以在控制器中使用Doctrine - 我应该像这样重新制作吗?
Class Link extends Link_base
{
public function getLinks()
{
return new Doctrine - here I build the query, SELECT, ORDER BY, etc;
}
}
控制器:
public function index()
{
$this->links = Links::getLinks();
}
我不确定哪种方式似乎没问题。当然,当选择需要更复杂的格式化todo-s时,它会转到模型或帮助器 - 但我觉得我只是制作了一个新的(不必要的)层。此getLinks()仅使用一次。换句话说:Doctrine可能只在模型中使用,或者也可以在控制器中使用?
答案 0 :(得分:2)
您的实体(或模型,如果您更喜欢该名称)应该不知道 如何从数据库中保存/检索它们。它们应该只是简单的PHP对象,只包含许多属性(对应于数据库列)及其getter和setter。
(如果您有兴趣,请阅读single responsibility principle,其中说明每个班级应该只有一个,而且只有一个责任。如果您让您的实体负责存储数据和知道如何在数据库中保存数据,当其中一个更改时,您将有更大的机会引入错误。)
您可以从控制器内部获取实体:
<?php
namespace Your\Bundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class LinkController extends Controller
{
public function fooAction()
{
$links = $this->getDoctrine()
->getRepository('YourBundle:Link')
->findAll();
// do something with the result, like passing it to a template
}
}
但是,您可能需要更复杂的查询(包括排序和过滤),您可能需要从多个控制器运行该查询。在这种情况下,您不希望将该逻辑复制到多个控制器,您希望将该逻辑保留在一个中心位置。
为此,请创建一个存储库:
<?php
namespace Your\Bundle\Repository;
use Doctrine\ORM\EntityRepository;
class LinkRepository extends EntityRepository
{
public function findAllOrderedByName()
{
return $this->getEntityManager()
->createQuery(
'SELECT l FROM YourBundle:Link l ORDER BY l.name ASC'
)
->getResult();
}
}
将存储库类添加到映射中:
Your\Bundle\Entity\Link:
type: entity
repositoryClass: Your\Bundle\Repository\LinkRepository
(如果您使用的是XML或注释而不是Yaml,请查看Symfony's documentation about custom repositories)
现在在您的控制器中,您只需更新fooAction
方法,以便它使用您的自定义存储库方法:
public function fooAction()
{
$links = $this->getDoctrine()
->getRepository('YourBundle:Link')
->findAllOrderedByName();
}
有关更多信息,Symfony的文档包含great article about Doctrine。如果你还没有这样做,我肯定会建议你阅读它。