当在使用Doctrine类时需要自定义查询时,有人可以为我提供一些明确的理由(支持事实)来使用/学习DQL与SQL吗?
我发现,如果无法使用ORM的内置关系功能来实现某些目标,通常会在扩展的Doctrine或DoctrineTable类中编写自定义方法。在这种方法中,用直接的SQL编写所需的代码(使用带有适当准备好的语句/注入保护的PDO等)。 DQL似乎是一种似乎无法学习/调试/维护的其他语言,它提供了足够的令人信服的理由来在大多数常见情况下使用。 DQL似乎并没有比SQL复杂得多,因此可以保证使用它-实际上,我怀疑您是否可以在没有扎实的SQL理解的情况下有效地使用DQL。在将与PHP一起使用的最常见数据库中,大多数核心SQL语法端口都相当不错。
我想念/忽略什么?我敢肯定有一个原因,但是我想听听那些有意大量使用它的人的消息,以及尝试使用纯OLE SQL带来的收益。
我不是在寻找支持ORM的参数,只是在传统的LAMP设置(使用mysql,postgres等)中需要执行核心"按关系获取"类型需求时执行的DQL。
我没有事实支持的参数,但是我发现名称关系比连接条件更易于使用,出错的几率更低,编写起来也很乏味。
老实说,我使用Doctrine1.2学习了SQL :)我什至不知道外键,级联操作,诸如group_concat之类的复杂功能以及许多其他东西。索引搜索也非常好用,可以直接使用。
DQL更加容易编写和理解代码。例如,此查询:
$query = ..... // some query for Categories
->leftJoin("c.Products p")
它将在类别和产品之间进行左连接,而您不必在p.category_id = c.id上写。
而且,如果将来您将关系从一个2到许多更改为很多2,那么这个查询将可以正常工作。教义将对此予以照顾。如果要使用SQL进行此操作,则必须更改所有查询以包括该中间多2多次表。
+1,尤其是对象之间的关系(外键)已在Base类中连接
Ive收到的回复中的@Zeljko,关于改变人际关系类型的答案中的最后一点是我所遇到的唯一令人信服的问题。我不太关心为什么它对那些不了解关系型数据库如何工作的人有益-从长远来看,对初学者来说并不总是最好的。另外,由于您注意到ON子句...有时您希望在ON子句中添加除键之外的其他条件-据我所知DQL不支持该条件。那是您需要完成的大多数工作的简单示例,但是在某些情况下却很难使用。
没错,您将有其他条款。对于这种情况,DQL提供了WITH语句。是的;一个人也可以与一对一,一对一,一对二,很多,许多二,许多...一起工作,而无需更改代码。我的建议:尝试一下。一旦上钩,就再也回不去了。就像驾驶顶级梅赛德斯车队与最底层的Yugo车队一样。两者都会把你从A点带到B点,但是我看不到Yugo形成的线。
@Zeljko,对我来说,这是比较错误的比较。 :)我从来没有说过,与普通的旧SQL相比,使用DQL可以实现更多或更多的稳定结果,或者更加轻松。也许是出于一些基本需求。它更多地是自动和手动档之间的比较。
我发现DQL更具可读性和方便性。如果正确配置,连接对象将更容易,查询也将更容易编写。
您的代码将很容易迁移到任何RDBMS。
最重要的是,DQL是对象模型而不是关系模式的对象查询语言。
我认为您的第一个是定性的-我已经看过真正复杂的DQL来完成简单的SQL查询可以解决的任务。您的第二点我完全同意,但是正如我的问题中所指出的,它不涉及实现DQL可以完成的所有工作所需的基本SQL。最后一点是最令人信服的方式。好的,它是对象而不是基础存储的查询语言。什么是对象查询语言的核心优势?它会提高性能吗?它是否支持经过严格审查的OO模式?它允许更有效/更好的代码吗?
@Ray在使用Doctrine 1.2之后,对性能确实有害。
你们有什么参考资料来理解教义生成的模型类(TestTable,BastTest,Test),以及如何正确处理它们,在控制器中调用谁?你能拜访我的问题stackoverflow.com/questions/11529224/
Zeljko的答案很明确。
使用DQL而不是原始SQL的最重要原因(在我的书中):Doctrine将实体与实体在数据库中的保存方式分开,这意味着实体不必随着基础存储的更改而更改。反过来,这意味着,如果您希望对基础存储进行更改(即重命名列,更改关系),则无需触摸DQL,因为在DQL中,您使用实体属性代替(这只会发生根据您的当前映射在幕后翻译以更正SQL)。
在过去一个月开发了一个应用程序并对数据库进行了许多更改之后,我同意这个答案。
使用DQL可帮助您处理对象。
万一插入到databae中,您将插入一个Object
$test = new Test();
$test->attr = 'test';
$test->save();
如果从数据库中选择,则将选择一个数组,然后将其填充到对象中
public function getTestParam($testParam)
{
$q=Doctrine_Query::create()
->select('t.test_id , t.attr')
->from('Test t ')
$p = $q->execute();
return $p;
}
您可以查看教义文档以获取更多详细信息