Hibernate中@MappedSuperclass对于继承映射有什么好处?

问题描述 投票:0回答:2

根据 Hibernate 文档

MappedSuperclass
允许映射继承,其中超类不被视为实体,并且不支持通过基类获取对象的多态查询。

另一方面,“每类一张表”策略在数据库中生成的模式方面类似,只是如果超类不是抽象类,它会将超类映射到表。然而它支持多态查询。 我的问题是:为什么有人会使用

@MappedSuperclass

策略?如果将父类视为实体,是否会隐含性能问题?任何有关此的想法都值得赞赏。

    

java hibernate
2个回答
11
投票
    @MappedSuperclass
    默认情况下,超类的属性被忽略并且不持久! 您必须使用
  • @MappedSuperclass

    注释超类,才能将其属性嵌入到具体的子类表中。

    
    

  • 您可以使用
  • @AttributeOverride

    注释或多个

    @AttributeOverrides
    重写子类中超类的列映射。
    
    

  • 您可以在超类中声明标识符属性,并为所有子类使用共享的列名和生成器策略,这样您就不必重复它。
  • 但这是可选的!

  • 隐式继承映射的主要问题是它不能很好地支持多态关联。在数据库中,通常将关联表示为外键关系。如果子类都映射到不同的表,则与其超类的多态关联不能表示为简单的外键关系。
  • 返回与被查询类的接口匹配的所有类的实例的多态查询也是有问题的。 Hibernate 必须将超类作为多个 SQL
  • SELECT

    执行查询,每个具体子类一个。

    
    

  • 此映射策略的另一个概念问题是不同表的几个不同列共享完全相同的语义。这使得模式演化变得更加复杂。例如,重命名或更改超类属性的类型会导致多个表中的多个列发生更改。 IDE 提供的许多标准重构操作都需要手动调整,因为自动过程通常不会考虑诸如
  • @AttributeOverrides

    之类的事情。它还使得实现适用于所有子类的数据库完整性约束变得更加困难。

    
    

  • 因此,对于类层次结构的顶层来说,这种方法是一个不错的选择, 通常不需要多态性,以及修改超类时 未来不太可能。

    @Inheritance(策略 = InheritanceType.TABLE_PER_CLASS)
  • 数据库标识符及其映射必须存在于超类中,以便在所有子类及其表中共享它。这不再是可选的,因为它是针对

    @MappedSuperclass 映射策略的。

    
    
    

  • 请注意,JPA 标准指定
  • TABLE_PER_CLASS

    是可选的,因此并非所有 JPA 实现都支持它。该实现也依赖于供应商 - 在 Hibernate 中,它相当于旧的本机 Hibernate XML 元数据中的

    <union-subclass>
    映射。
    
    

  • 如果我们检查多态查询,这种映射策略的优点会更加明显。使用 UNION 运算符将表组合在一起,并将文字插入到中间结果中; Hibernate 读取此内容以根据特定行的数据实例化正确的类。联合要求组合的查询投射到相同的列上;因此,您必须用 NULL 填充不存在的列。您可能会问这个查询是否真的比两个单独的语句执行得更好。在这里,您可以让数据库优化器找到最佳执行计划来组合多个表中的行,而不是像 Hibernate 的多态加载器引擎那样合并内存中的两个结果集。
  • 另一个更重要的优点是处理多态关联的能力。 Hibernate 可以使用
  • UNION

    查询来模拟单个表作为关联映射的目标。

    
    

  • 因此,当您需要使用多态查询和关联时,这种方法是一个不错的选择。

附注这几乎是逐字引述的优秀书籍:

Java Persistence with Hibernate

(Bauer、King、Gregory)


-1
投票

© www.soinside.com 2019 - 2024. All rights reserved.