Symfony 在web应用程序中使用什么原则方法?

Symfony 在web应用程序中使用什么原则方法?,symfony,doctrine,Symfony,Doctrine,我正在用symfony2构建web应用程序。我用条令作为数据库引擎。我需要使用一些复杂的数据库查询来接收mysql数据库中的数据。我发现(如果我错了,请纠正我)是: DQL—在对象(getter、setter等)上进行操作时,它很有用。不幸的是,如果我的应用程序使用复杂的sql查询(许多左连接、内部连接等),则没有多大帮助 原生SQL—我不确定这种方法。不能对这些物体进行操作吗?我在创建联接查询时遇到了困难 原始SQL-任何SQL查询都是可能的,但我不能使用对象 即使在应用程序和数据库之间有OR

我正在用symfony2构建web应用程序。我用条令作为数据库引擎。我需要使用一些复杂的数据库查询来接收mysql数据库中的数据。我发现(如果我错了,请纠正我)是:

  • DQL—在对象(getter、setter等)上进行操作时,它很有用。不幸的是,如果我的应用程序使用复杂的sql查询(许多左连接、内部连接等),则没有多大帮助
  • 原生SQL—我不确定这种方法。不能对这些物体进行操作吗?我在创建联接查询时遇到了困难
  • 原始SQL-任何SQL查询都是可能的,但我不能使用对象

  • 即使在应用程序和数据库之间有ORM层,有时也需要编写原始SQL查询;例如,如果您正在生成关于应用程序使用情况的报告,或者正在计算中间数据,等等

    但是,在每种情况下,您都应该问问自己,使用对象而不是原始数据是否更合适。在许多情况下,人们认为如果不直接进入数据库级别,就无法实现结果,但他们可能会惊讶地发现,使用类似ORM的现代理论,您可以做很多事情

    在原则中,连接由关联表示,系统的一个关键好处是可以通过对象而不是原始SQL与关联交互

    考虑下面的“复杂”查询(好吧,其实并没有那么复杂):

    在条令中,您可以使用实体对此进行建模。例如,一个代码段:

    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     * @ORM\Table(name="foo")
     */
    class Foo
    {
      /**
       * @ORM\Id
       * @ORM\Column(name="foo_id", type="integer")
       * @ORM\GeneratedValue
       */
      private $id;
    
      /**
       * @ORM\Column(name="foo_name", type="string", length=32)
       */
      private $name;
    
      /**
       * @ORM\OneToMany(targetEntity="Bar", mappedBy="foos")
       */
      private $bars;
    
      // more code ...
    
    }
    
    还有一个:

    use Doctrine\ORM\Mapping as ORM;
    
    /**
     * @ORM\Entity
     * @ORM\Table(name="bar")
     */
    class Bar
    {
      /**
       * @ORM\Id
       * @ORM\Column(name="bar_id", type="integer")
       * @ORM\GeneratedValue
       */
      private $id;
    
      /**
       * @ORM\Column(name="bar_name", type="string", length=32)
       */
      private $name;
    
      /**
       * @ORM\ManyToOne(targetEntity="Foo", inversedBy="bars")
       * @ORM\JoinColumn(name="foo_id", referencedColumnName="foo_id")
       */
      private $foo;
    
      // more code ...
    
    }
    
    现在,在DQL中,我们可以重写原始查询:

    SELECT f, b
    FROM \Your\Namespace\Foo f
    LEFT JOIN f.bars b
    WHERE f.name = "x"
    
    此查询将生成一个或多个Foo对象,以及与每个对象关联的任何Bar对象,所有这些对象都只包含对数据库的单个查询。使用此模式,您应该能够用对象对绝大多数有用的SQL查询进行建模,使它们的关系自然且易于理解

    另一件值得注意的事情是,上面的DQL查询实际上被称为“fetch join”,因为它将同时包含被请求的Foo对象和与之关联的任何Bar对象。更简单的查询版本是:

    SELECT f
    FROM \Your\Namespace\Foo f
    WHERE f.name = "x"
    
    这将在第一个查询中只生成Foo对象,不执行连接。但是,您仍然可以访问相关的Bar对象(例如,
    $foo->getbar()
    ),并且条令将根据需要自动获取相关数据(这称为“延迟加载”)。在所有情况下,您都可以自由地决定是否要为实体添加部分或全部对象图,或者只检索顶级数据并允许Doctrine根据需要加载数据


    有关这方面的信息有很多。

    DQL允许复杂的连接,您只需将它们视为对象即可。如果您已经了解SQL,DQL将需要您一点时间来学习,这是一种不同的思维方式,但从长远来看,它将节省您一些时间,因为它更易于编写。哎呀,我在想,不是DQL。
    SELECT f
    FROM \Your\Namespace\Foo f
    WHERE f.name = "x"