真正复杂查询的 ORM 解决方案
Posted
技术标签:
【中文标题】真正复杂查询的 ORM 解决方案【英文标题】:ORM Solution for really complex queries 【发布时间】:2011-10-25 16:16:39 【问题描述】:可以/应该使用任何 ORM 解决方案是这样的复杂情况吗?
这甚至可以用 Propel
或 Doctrine
完成吗?目前我正在使用 Propel。所以如果有 Propel 解决方案,我会很高兴。
如果我用 propel 直接查询,有什么建议?
SELECT I.*,((I.width*175)/I.height) as relativeWidth FROM
(SELECT * FROM Image WHERE owner = 1 LIMIT 5, 10) I
order by relativeWidth asc
此外,对于需要在应用程序的大多数地方执行非常复杂的查询的场景,标准解决方案是什么?
有一个LIMIT 5, 10
用于分页。及其在内部查询中。如果它在视图中,我该如何控制分页?
【问题讨论】:
相关问题:***.com/questions/7860871/… 这个问题也是我问的 是的,我知道 - 对人们看到它很有用。 【参考方案1】:您的查询可以用 Propel 1.6.3 编写如下:
<?php
// SELECT * FROM Image WHERE owner = 1 LIMIT 5, 10
$subQuery = ImageQuery::create()
->filterByOwner(1)
->limit(10)
->offset(5)
;
$query = ImageQuery::create()
->addSelectQuery($subQuery, 'I', true)
->withColumn('((I.WIDTH*175)/I.HEIGHT)', 'relativeWidth') // ((I.width*175)/I.height) as relativeWidth
->orderBy('relativeWidth') // default is 'asc'
;
$params = array();
var_dump(\BasePeer::createSelectSql($query, $params));
输出是:
SELECT I.ID, I.WIDTH, I.HEIGHT, I.OWNER, ((I.WIDTH*175)/I.HEIGHT) AS relativeWidth
FROM (
SELECT image.ID, image.WIDTH, image.HEIGHT, image.OWNER
FROM `image`
WHERE image.OWNER=:p1 LIMIT 5, 10
) AS I
ORDER BY relativeWidth ASC
注意:p1
是与所有者值相关的绑定参数。
所以使用 Propel 创建复杂的查询真的很容易 :)
威廉
【讨论】:
【参考方案2】:有些查询最好用视图来解决,imo。诚然,这不适合 ORM 纯粹主义者,但我发现它是一种非常可维护的方法,同时还能获得 ORM 的好处。我想说的是,在一个项目中,你应该只在 10% 左右的时间里这样做;如果您发现您正在为大多数 ORM 语句编写视图,那么可能需要另一种方法。
说了这么多,你举的例子很简单。根据我在相关问题上的示例,我倾向于在对等类中使用原始 SQL 编写一种特殊方法,并手动对其进行水合。请记住,在运行原始 sql 时,更容易成为 SQL 注入的牺牲品 - 记住要转义、清理或参数化您的变量。
【讨论】:
在 ORM 中使用视图并没有错,它实际上会让 DBA 成为我们最好的朋友。 但是在我给出的查询中LIMIT 5, 10
用于内部查询中的分页,如果它在视图中我无法控制!!
请检查我在问题中的编辑
啊,我现在明白 LIMIT 语句的用途了。在 Propel 中执行此操作,而不是在您的查询中。 $c->setLimit() 如果你使用 Criteria; Query 方法也可以使用类似的东西。
如何在推进中做到这一点?它在内部查询中!!以上是关于真正复杂查询的 ORM 解决方案的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Python 中将(有些复杂的)Postgresql 语句转换为 SQLAlchemy ORM?