gpt4 book ai didi

java - 在没有ORM的情况下在sql中映射一对多的方法

转载 作者:行者123 更新时间:2023-11-30 05:46:43 25 4
gpt4 key购买 nike

假设我有一个实体。

class Building {
List<Floor> floors;
List<Elevator> elevators;
}

为了简单起见,楼层和电梯只有id 。建筑有id, elevator_id, floor_id

因此,获取具有所有楼层和所有电梯的所有建筑物的查询将是:

select 
id,
floor.id as floor_id,
elevator.id as elevator_id
from building
left join floor on (floor.building_id = building.id)
left join elevator on (elevator.building_id = building.id)

现在假设我有一栋 2 层楼和 2 部电梯的建筑。查询将给出如下结果集:

 id|floor_id|elevator_id
1 f1 e1
2 f2 e2
1 f1 e2
2 f2 e1

所以有 4 条记录。解析方式:

  1. 不要逐行,而是逐列。
  2. 单独创建每个实体
  3. 删除重复项
  4. 将所有实体合并到正确的结构中。

所以问题是 - 有没有更好的方法来解决这个问题? ORM 在幕后是否也做同样的事情?

不寻找特定的库,因为我试图弄清楚它是如何工作的。

最佳答案

运行多个查询

智能 ORM 应运行 2-3 个查询:

  1. 获取所有建筑物及其楼层的查询
  2. 获取楼层的查询(如果尚未获取)
  3. 获取所有电梯的查询

执行这些查询后,可以在客户端中再次合并数据。无论是在 SQL 中还是在 ORM 中,使用多左连接一次性完成这一切都不是一个好主意,因为您将使用建议的 SQL 在楼层和电梯之间创建笛卡尔积。想象一下,如果两个左连接为每个建筑物生成 1000 行,您将获得 1000000 行重复数据,即使每个建筑物只有 2000 个子建筑。

关于多重集的旁注

请注意,SQL 标准有一个 MULTISET() 运算符,这将是这里的最佳选择,但很少有 RDBMS 实现它:

select 
building.*,
multiset(select * from floor where floor.building_id = building.id),
multiset(select * from elevator where elevator.building_id = building.id)
from building

许多数据库支持 XML 和 JSON,因此如果您能够足够好地抽象它,使用这些格式的解决方法可能有助于解决这个问题。我不知道目前有任何 ORM 在 Java 中执行此操作。 jOOQ has it on the roadmap ,但没有实现。 Neither is Hibernate's version .

关于java - 在没有ORM的情况下在sql中映射一对多的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54706220/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com