使用Doctrine使用DQL而不是SQL有什么好处?

问题描述:

有人可以提供一些明确的(事实支持)理由来使用/学习DQL与SQL,当需要一个自定义查询时使用Doctrine Classes?使用Doctrine使用DQL而不是SQL有什么好处?

我觉得,如果我不能使用ORM的内置关联功能来实现的东西我平时写在扩展学说或DoctrineTable类的定制方法。在这种方法中,将所需的数据写入直接的SQL(使用具有适当的准备语句/注入保护等的PDO)。 DQL看起来像学习/调试/维护的附加语言似乎没有提供足够令人信服的理由在大多数常见情况下使用。 DQL似乎并不比SQL复杂得多,因为我们怀疑如果没有扎实的SQL理解,就可以有效地使用DQL。大多数核心SQL语法端口在您使用PHP的最常用数据库中相当好。

我在想什么/忽略?我确信有一个原因,但我想听听那些有意使用它的人,以及尝试使用plain-ole SQL的好处。

我不是在寻找支持的ORM的说法,只是DQL需要做核心“得到逐关系”型需求之外的东西,在传统的LAMP设置时(使用MySQL,Postgres的,等等。 )

+3

我没有事实支持的参数,但是我发现名称关系比联接条件更容易使用,不易出错并且编写起来很繁琐。 – 2012-07-17 20:42:23

说实话,我学会了SQL使用Doctrine1.2 :)我甚至没有意识到外键,级联操作,像group_concat和许多其他许多复杂的功能。索引搜索也是非常好用和便利的事情,可以直接使用。

DQL要简单得多,编写和理解的代码。例如,下面的查询:

$query = ..... // some query for Categories 
    ->leftJoin("c.Products p") 

它会做左类别和产品之间的连接,你不必写在p.category_id = c.id。

而且如果将来你从一个-2-许多变化的关系,让我们说很多-2-许多,同样的查询将没有任何变化在所有的工作。主义会照顾到这一点。如果你使用SQL来完成这项工作,那么所有的查询都必须被修改,以包含那个中间的2-many表。

+0

+1,尤其是对象之间的关系(外键)已经连接在我收到回复的基础类 – KJA 2012-07-19 08:59:11

+1

@Zeljko中,您对关于改变关系类型的答案的最后一点是对我的情况唯一有吸引力的答案。我并不关心为什么对于那些不了解关系数据库的工作原理的人来说,这对于初学者来说并不总是最好的。另外,既然你注意到了ON子句......有时候你想添加除'ON'子句中的键之外的其他标准 - 就我所知,DQL不支持这一点。这是您需要做的大部分工作都很容易的例子,但在某些情况下极难使用。 – Ray 2012-07-20 13:41:18

+0

你说得对,你会有附加条款。在这种情况下,DQL提供'WITH'语句。是的;那个人也可以同时使用一对一,一对多,多对多......不用改变代码。 我的建议:尝试一下。一旦你迷上了,你将永远不会回头。这就像驾驶梅赛德斯顶级赛车与底线级别Yugo一样。两者都会将你从A点带到B点,但我看不到为Yugo形成的线条。 – Zeljko 2012-07-21 14:29:23

我发现DQL更具可读性和方便。如果你正确地配置它,连接对象会更容易,查询将更容易编写。

您的代码将很容易迁移到任何RDBMS。

而且最重要的,是DQL对象查询语言对象模型,而不是你的关系模式。

+0

我认为你的第一个是定性的 - 我已经看到真正复杂/复杂的DQL来完成一个简单的SQL查询可以解决的任务。你的第二点我完全同意,但正如我的问题所指出的那样,对于涵盖DQL所能完成的所有事情所需的基本SQL而言,并不值得关注。你最后一点是最有说服力的方法。好的,这是一个查询语言,而不是底层存储的对象。什么看作是查询语言的核心优势?它会提高性能吗?它是否支持经过充分审查的面向对象模式?它是否允许更高效/更好的代码? – Ray 2012-07-18 12:47:49

+0

@Ray在使用Doctrine 1.2之后,对性能确实有害。 – KJA 2012-07-19 09:05:21

+0

你有没有任何参考资料可以理解教义生成的模型类(TestTable,BastTest,Test)以及如何正确处理它们,谁在控制器中调用? 可以请你访问我的问题http://stackoverflow.com/questions/11529224/doctrine-table-vs-class-that-extends-from-baseclass – KJA 2012-07-19 10:26:24

使用DQL可以帮助您处理对象。 的情况下,插入databae,你会插入对象

$test = new Test(); 
$test->attr = 'test'; 
$test->save(); 

从databae选择的情况下,你会选择一个数组,然后你可以填写在你的对象

public function getTestParam($testParam) 
    { 
     $q=Doctrine_Query::create() 
       ->select('t.test_id , t.attr') 
       ->from('Test t ') 
      $p = $q->execute(); 
      return $p; 
    } 

您可以检查该教义文档的更多细节

Zeljko的回答很有用。

使用DQL而不是原始SQL的最重要原因(在我的书中):Doctrine将实体与它在数据库中的存储方式分离开来,这意味着实体不必更改为底层存储更改。这反过来又意味着,如果您希望对底层存储进行更改(即重命名列,更改关系),则不必触摸DQL,因为在DQL中,您使用实体属性(而这只发生在根据你当前的映射,在后台进行编译以纠正SQL)。

+0

在上个月的应用程序工作并对数据库进行了许多更改之后,我同意这个答案。 – kiwicomb123 2018-01-10 00:05:32