根据Hibernate 文档,MappedSuperclass允许映射继承,其中超类不被视为实体,并且不支持通过基类获取对象的多态查询。
另一方面,每个班级的表策略在数据库中生成的模式方面是类似的,只是如果超类不是抽象的话,它会将超类映射到表。但是它支持多态查询。
我的问题是:为什么有人会使用该@MappedSuperclass策略?如果将父类视为实体,是否会隐含性能问题?任何与此相关的想法都值得赞赏。
Ste*_*rnK 10
默认情况下,超类的属性被忽略并且不持久!\n您必须使用以下注释超类@MappedSuperclass才能将其属性嵌入到具体的子类表中。
@AttributeOverride您可以使用注释或多个注释覆盖子类中超类的列映射@AttributeOverrides。
您可以在超类中声明标识符属性,并为所有子类使用共享列名和生成器策略,这样您就不必重复它。但它\xe2\x80\x99是可选的!
\n隐式继承映射的主要问题是它不能很好地支持多态关联。在数据库中,通常将关联表示为外键关系。如果子类都映射到不同的表,则与其超类的多态关联可以\xe2\x80\x99 表示为简单的外键关系。
\n返回与被查询类的接口匹配的所有类的实例的多态查询也是有问题的。Hibernate 必须将超类作为多个 SQL 执行查询SELECT,每个具体子类一个。
此映射策略的另一个概念问题是不同表的几个不同列共享完全相同的语义。这使得模式演化变得更加复杂。例如,重命名或更改超类属性的类型会导致多个表中的多个列发生更改。IDE 提供的许多标准重构操作都需要手动调整,因为自动过程通常不考虑@AttributeOverrides. 它还使得实现适用于所有子类的数据库完整性约束变得更加困难。
因此,对于类层次结构的顶层来说,这种方法是一个不错的选择,\n通常不需要多态性\xe2\x80\x99,并且当未来不太可能修改超类时。
\n数据库标识符及其映射必须存在于超类中,以便在所有子类及其表中共享它。这不再是可选的,因为它对于@MappedSuperclass映射策略来说是可选的。
请注意,JPA 标准指定这TABLE_PER_CLASS是可选的,因此并非所有 JPA 实现都支持它。Hibernate 中的实现也是依赖于供应商的 \xe2\x80\x94,它的 \xe2\x80\x99 相当于<union-subclass>旧的本机 Hibernate XML 元数据中的映射。
如果我们检查多态查询,这种映射策略的优点会更加明显。使用 UNION 运算符将表组合在一起,并将文字插入到中间结果中;Hibernate 读取此内容以根据特定行的数据实例化正确的类。联合要求组合的查询投射到相同的列上;因此,您必须用 NULL 填充不存在的列。您可能会问这个查询是否真的比两个单独的语句执行得更好。在这里,您可以让数据库优化器找到最佳执行计划来组合多个表中的行,而不是像 Hibernate\xe2\x80\x99s 多态加载器引擎那样合并内存中的两个结果集。
\n另一个更重要的优点是处理多态关联的能力。Hibernate可以使用UNION查询来模拟单个表作为关联映射的目标。
因此,当您需要使用多态查询和关联时,这种方法是一个不错的选择。
\nPS 这几乎是逐字引述的优秀书籍:Java Persistence with Hibernate(Bauer、King、Gregory)
\n| 归档时间: |
|
| 查看次数: |
8781 次 |
| 最近记录: |