我有一个连接5个表的查询。 然后我用我需要的列值填充手工制作的对象。
这里使用特定工具解决该问题的解决方案是什么?有这样的工具吗?
我刚刚开始学习Hibernate,所以我的问题是:Hibernate对这个问题是正确的决定吗?
Hibernate将表映射到类。所以,如果我有5个类而不是5个表没有区别。将查询结果加入类
仍然很困难可以使用hibernate将QUERY映射到我预先定义的结构(类)中,就像我们使用表映射一样吗?或者甚至更好,是否可以将查询结果映射到有意义的字段[自动创建带字段的类],就像使用逆向工程一样?
我一直在考虑视图,但每次我们需要一个复杂的查询时都会创建一个新的视图..太冗长了。 的
正如S.Lott所问,这是一个问题的简单版本:
一般问题:
select A.field_a, B.field_b, C.field_c from table_a A inner join table_b B inner join table_c C where ...
每个表包含100个字段 查询返回3个字段,但每个字段都属于唯一表
如何以OO风格解决该问题? 设计一个新对象,其属性对应于查询的返回值。
我想知道这是否是正确的(也是唯一可能的)决定,是否有任何共同的解决方案。
另见我的评论。
答案 0 :(得分:1)
ORM的目的是将对象映射到关系。
ORM的意思是 - 明确地 - 不以扼杀特定SQL连接的细节。
理解ORM的一个基本原则是这个。
SQL连接是一种黑客攻击,因为SQL没有正确的导航。
要进行ORM设计,我们要故意将SQL连接注意事项设置为(很大程度上)不相关。放弃旧的方式。没关系,真的。 SQL拐杖并不能很好地支持我们。
步骤1.定义话语领域。现实世界的对象。
步骤2.定义作为真实世界事物的高保真模型的实现类。
步骤3.将对象映射到关系。这是黑客入侵的地方。 SQL没有各种集合 - 它只有表。 SQL没有子类,只有表。所以你必须在对象类和表之间设计一个“足够好”的映射。理想情况下,这是一对一的。但实际上,它并没有那么成功。通常,您将使用一些非规范化来处理类层次结构。除此之外,它应该运作得相当好。
是的,你必须添加没有对象映射的多对多关联表。
第4步。你已经完成了。写下你的申请。
“但是我的查询加入5(或3)个表但只从每个表中获取一个属性呢?”
怎么样?其中一个表是您正在处理的真实对象。这5个(或3个)表中的另一个是1-m嵌套集合,m-1个容器或m-m关联的一部分。这只是对象之间的导航。
1-m嵌套集合是SQL将其视为“结果集”的东西。在ORM中,它将成为正确的对象集合。
m-1包含是典型的FK关系。在ORM中,它只是通过普通对象导航获取相关对象。
m-m关联也是一个对象集合。这是一个奇怪的集合,因为两个对象是彼此集合的成员,但它只是一个对象集合。
您在任何时候都没有设计与查询匹配的对象。您设计了一个与现实世界相匹配的对象,并将其映射到数据库。
“性能怎么样?”当您破坏ORM的简单映射规则时,这只是一个问题。进入蓝色月亮后,您必须创建一个专用视图来处理对象之间非常大的面向批处理的连接。但这真的很少见。通常,重新思考Java程序的导航模式将提高性能。
请记住,ORM会缓存您的结果。每个“导航”可能不是数据库查询的完整“往返”。某些查询可能由ORM为您批量处理。
答案 1 :(得分:1)
有几个选择:
<join>
元素创建单个表映射。以这种方式进行连接将允许其他表为您的类提供属性。<class name=... table=...
代替<class name=... select="select A.field_a, B.field_b, ... from A, B, ...">
。它本质上是在Hibernate端创建一个视图,因此数据库不必更改。生成的sql最终看起来像“select * from (select A.field_a, B.field_b from A, B, ...)
“。我知道它适用于Oracle,DB2和MySQL 所有这一切都可以选择;如果您需要进行插入/更新,您可能需要重新考虑数据模型或对象模型。
答案 2 :(得分:0)
我认为您可以使用Hibernate中的Criteria API将您的联接结果映射到您的目标类。