【问题标题】:OR-Mapping Across Tables跨表或映射
【发布时间】:2012-01-17 20:43:13
【问题描述】:

我确信不同的 ORM 工具以不同的方式解决问题,但是对于 or-mapping 的概念来说是全新的,我并不真正关心具体的实现,因为我是一个通用的解决方案。如果没有特定的 ORM 框架根本无法回答这个问题,那么让我们使用 Hibernate。

我了解或映射的基本前提,但是我很好奇这些框架如何处理跨多个表的查询,例如当查询中出现JOINs 时会发生什么。

SELECT f.fizz_name, b.buzz_foo
FROM fizz f
INNER JOIN buzz b
ON f.buzz_id = b.buzz_id
WHERE b.buzz_bar < 10

现在我们没有从 or-mapper 得到一个漂亮、干净、单一的 POJO。我想知道这是否是一个 or-mapping 崩溃的领域,而直接 JDBC 是程序员必须使用的全部。

老实说,我自己尝试了一下,但在 Hibernate 文档中找不到任何说明在这种情况下会发生什么的内容。

提前致谢!

【问题讨论】:

标签: java sql hibernate orm inner-join


【解决方案1】:

正如您所指出的,不同的 ORM 工具可能会以不同的方式处理它,但在 hibernate 中,您会得到一个数组列表,其中每一列都是 Object[] 中的一个对象。

See section 16.6 here 以获得更多解释。

关键是您不需要使用普通 sql 从连接查询中获取结果,至少使用 Hibernate。

【讨论】:

    【解决方案2】:

    我熟悉的大多数 ORM 框架允许您将来自不同表的任意字段映射到单个代码对象。但是,如果您发现自己需要这样做,您应该立即问自己为什么当代码表明合在一起合乎逻辑时,数据分散在数据库中。

    几乎所有发生这种情况的情况下,要么是对象的代码表示太大,需要分解成它的组成部分,要么是对象的 DB 表示是碎片化的,并且数据的相关性比数据库显示的要高。

    如何处理它的细节因 ORM 不同而不同,但 hibernate 有许多不同的方法来处理这个问题,包括在字段的映射中指定特定的查询。

    【讨论】:

      【解决方案3】:

      这个问题最终可能会引发关于object-relational impedance mismatch 的深入讨论。为避免这种讨论,您应该问问自己您是在设计 OLTP 还是 OLAP 应用程序。

      • OLTP:您的 JPA 实体大多直接映射到基础表,您可以轻松地对它们执行 CRUD 操作,读取、删除、存储它们。正如hvgotcodes here 所指出的那样,连接可以看作是一种将来自各种实体的数据关联起来以创建谓词的工具,但通常您不会使用自定义投影创建新的临时类型。那么,Hibernate 非常适合您。

      • OLAP:您的 JPA 实体几乎不会映射到任何基础表,因为您要使用自定义投影 (SELECT f.fizz_name, b.buzz_foo) 创建的类型可以是列/函数/聚合的任意组合。这与连接本身无关,而是与您创建任意投影的事实有关。

      正如ChssPly76 指出的那样,您的示例仍然很简单,Hibernate 可以很好地处理它。为了获得您想要的 POJO,您可以执行以下操作(来自文档):

      select new Family(mother, mate, offspr)
      from DomesticCat as mother
          join mother.mate as mate
          left join mother.kittens as offspr
      

      但是,如果您深入了解 OLAP,您可能会发现 Hibernate(HQL、JPQL)的表现力不够。这就是 JDBC、jOOQmybatisSpring Templates 可能更适合的地方。

      【讨论】:

        猜你喜欢
        • 2012-11-23
        • 2018-07-13
        • 2015-03-15
        • 1970-01-01
        • 2018-11-28
        • 2023-03-08
        • 2012-08-29
        • 2011-06-06
        • 2012-07-01
        相关资源
        最近更新 更多