真正复杂查询的 ORM 解决方案

Posted

技术标签:

【中文标题】真正复杂查询的 ORM 解决方案【英文标题】:ORM Solution for really complex queries 【发布时间】:2011-10-25 16:16:39 【问题描述】:

可以/应该使用任何 ORM 解决方案是这样的复杂情况吗? 这甚至可以用 PropelDoctrine 完成吗?目前我正在使用 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?

具体复杂的 SQL 查询和 Django ORM?

使用 Rest API 编写复杂查询的 Django ORM

学说 2 和 ORM:如何缓存某个实体的每个查询?

django orm总结--解决查询结果不区分大小写问题

2022-01-19.tortoise-orm执行原生sql语句