在模型中放置数据库查询的位置?(Symfony框架)


Where to place a database query in model? (Symfony framework)

我是PHP编程和Symfony的新手。英语不是我的母语,所以很抱歉,如果我的写作方式听起来很奇怪。。。

我有两个实体:文章类别,其中每个文章都有一个类别。我需要展示我在一个特定类别中有多少篇文章:

类别------------------

车辆-------------------4

电子----------------20

食品------------------------15

家具-------------------8

使用Doctrine,我为这两个实体制作了CRUD文件。

 php app/console doctrine:generate:crud 

正如我所说,问题是我想显示一个具有类别属性(名称、描述等)的表,以及库存中有多少文章。

SQL查询非常简单:

SELECT count(*) FROM Articles a WHERE a.id_category = $id_category

放在哪里?!我很困惑,不想破坏最佳实践规则。Doctrine生成了许多文件:ArticleController.php、ArticleType.php(Form),以及视图的所有.titch。类别相同。

本着直接回答您的问题的精神:您需要的是一个自定义的条令库,在本例中是ArticleRepository

例如。ArticleRepository.php

namespace ACME'DemoBundle'Article;
use Doctrine'ORM'EntityRepository;
class ArticleRepository extends EntityRepository
{
    public function countForCategory($id)
    {
        $result= $this->createQueryBuilder('a')
            ->join('a.category', 'c')
            ->where('c.category_id = :id')
            ->setParameter('id', $id)
            ->select('count(a')
            ->getQuery()
            ->getSingleScalarResult();
        return $result;
    }
}

然后你设置你的文章实体使用ArticleRepository

文章.php

/**
 * @ORM'Entity
 * @ORM'Table(name="article")
 * @ORM'Entity(repositoryClass="ACME'DemoBundle'Entity'ArticleRepository")
 */
class Article
{
/// etc...

然后,您可以在例如您的控制器中获取实体的存储库(尽管如其他地方所建议的,您可以将其隐藏在某种服务中,以避免用业务逻辑填充控制器;它只需要从控制器内部以某种方式可访问),并运行查询:

文章控制器

class ArticleController extends Controller
{
    public function countAction($id)
    {
        $articleRepo = $this->getDoctrine()->getRepository('DemoBundle:Article');
        $count = $articleRepo->countForCategory();
        //etc...

注意:如果您真的想要示例中的输出,那么对整个表执行一个查询可能会更高效,可能是在CategoryRepository中,执行计数并按类别分组。查询将返回一个包含Category名称和计数的数组。

使用Symfony2+Doctrine2时,

  1. 不要对数据库想太多。考虑持久数据对象,即所谓的实体,并让Doctrine处理它们。不过,花一些时间来干净地定义这些对象之间的关系。

  2. 忘掉"MVC"这个术语吧。MVC是一个相当抽象的概念,现实中的事情更为复杂。Fabian(SF的首席开发人员)对这个主题写了一篇很好的文章:http://fabien.potencier.org/article/49/what-is-symfony2

如果你想知道在你的Symfony包里放什么,请阅读这篇食谱文章:http://symfony.com/doc/current/cookbook/bundles/best_practices.html

在服务层中创建一个CategoryManager类,并在那里处理任何业务逻辑。您可以通过依赖项注入将路由器传递给它。

例如,CategoryManager将有一个getUrl(Article$Article)方法,该方法将使用路由器实例(通过__construct或单独的setter方法注入)根据$Article的属性生成Url并返回。

此方法将确保您的业务逻辑不会污染视图或控制器层。

检查此链接Services Symfony