假设我有一个实体。
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条记录。解析它们的方式:
问题是-是否有更好的方法来解决问题?而且ORM是否在幕后做同样的事情?
因为要弄清楚它的工作原理,所以没有寻找特定的库。
答案 0 :(得分:1)
智能ORM应该运行2-3个查询:
一旦执行了这些查询,就可以在客户端中再次合并数据。无论是在SQL中还是在ORM中,都不是一个好主意,因为要使用建议的SQL在地板和电梯之间创建笛卡尔积,因此要使用多个左联接一次性完成所有操作。想象一下,如果两个左联接在每个建筑物中都产生1000行,即使每个建筑物只有2000个子级,您也会得到1000000行重复数据。
请注意,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,因此,如果可以将其抽象得足够好,则使用这些格式的解决方法可能有助于解决此问题。我不知道目前在Java中执行此操作的任何ORM。 jOOQ has it on the roadmap,但尚未实现。 Neither is Hibernate's version。