【问题标题】:How to map dynamically a single entity class to multiple tables?如何将单个实体类动态映射到多个表?
【发布时间】:2013-10-15 00:04:06
【问题描述】:

由于与现有遗留代码和流程相关的各种原因,我希望能够使用 Hibernate 将单个实体类映射到具有相同结构的不同表。这些表是在运行时从另一个已知表动态创建的。因此,例如,我将有以下课程:

public class Item {

   private int id;
   private String label;
    ...
}

这将被映射到 3 个不同的表,ITEM1ITEM2ITEM3 都具有相同的结构:

 CREATE TABLE ITEM[1|2|3] (
    NUMBER id PRIMARY KEY,
    VARCHAR label NOT NULL)

如上所述,表将根据一些外部配置/条件在运行时创建。

我已经查看了关于 SO 的以下问题:

虽然可能,但建议的解决方案(子类化)并不是很吸引人。这意味着运行时动态类创建的一些黑魔法,如果可以的话,我宁愿避免。

来自thisthis 的博文,我相信可以创建动态Hibernate 映射,将同一个实体映射到多个表。

有没有人有更多实现这种动态映射的经验?

【问题讨论】:

    标签: java hibernate jpa orm


    【解决方案1】:

    以防万一,我是你提到的博客文章的作者。

    让我们把你的问题分成两部分:

    1. 是否可以将同一个类映射到多个表而不进行子类化?
    2. 是否可以在运行时调整映射以适应新表?

    1. 的答案是:是的,如果您不使用基于注解的映射并且您将同一类映射到不同的实体名称下。您发布的第二个链接 (How to map one class to different tables using hibernate/jpa annotations) 暗示了该解决方案;您可以使用 HBM 文件,当然也可以使用编程配置。您必须使用更详细的 save()、update() 等重载,这些重载允许将实体名称指定为额外参数。

    2.的答案是:是和不是;您可以使用新映射和旧映射一起重建一个全新的 SessionFactory(就像我们在 Portofino 中所做的那样),但是您不能以编程方式将新映射添加到现有 SessionFactory。这意味着在某一时刻,您必须关闭所有现有会话,处理旧的 SessionFactory,构建新的会话工厂并开始使用它。换句话说,是的,您可以在运行时执行此操作,但不能与同一会话工厂的其他用途无缝且同时进行。您当然可以使用多个 SessionFactories 来拆分映射或提供冗余映射并处理优雅的更新方案;这真的取决于你的要求。

    【讨论】:

    • 感谢您的回答。与此同时,我开始按照您博客文章的总体思路使用代码,并设法获得 1. 工作,手动构建 RootClass 和映射。我从第 2 点和我自己的经验了解到,不可能使用现有会话更改映射,无论如何这可能是个坏主意。我现在要做的是从注释构建一个映射,并在开始使用它之前对其进行调整:这将大大减少要编写的样板文件的数量。你在波托菲诺试过吗?
    • 非常有趣!不,我们没有尝试过,因为我们的输入是我们自己的 xml 模型格式,它描述了数据库的结构和映射。我们不映射到带注释的 Java 类,而是映射到 hashmap。但是,我们多次考虑过允许用户提供自己现有的注释类或 hbm 文件的可能性;只是还没有成为优先事项。
    • 我实际上放弃了这条路,因为我认为我们正试图将方钉放在圆孔中:Hibernate 和一般 ORM 对映射 entities 很有用,而不是作为通用访问层到 RDBMS。在我们的特定情况下,最好使用纯 JDBC 访问而不依赖 ORM 来满足需求,因为我们基本上使用 DB 作为消息队列的持久存储,每个消费者都有自己的队列映射到特定的表。无论如何,感谢您分享您的见解。
    • 嗯,这是有道理的。我们使用 Hibernate 是因为我们的产品是通用的,并且 Hibernate 提供了一个众所周知的 API,并且在不排除在必要时使用直接 SQL 的可能性的情况下抽象出数据库系统之间的许多微小差异。然而,使用 Hibernate 并不是一个不折不扣的解决方案,对于某些特定的用例,它可能比好的旧 JDBC 更麻烦。你考虑过 myBatis 吗?我不知道第一手,但据说它比 Hibernate 低级,对纯 SQL 使用更友好,同时仍然提供一些 OO 好处。
    • 是的,myBatis 是一个很棒的工具,当它被称为 iBatis 时,我曾经使用它。我发现它简单高效,宁愿使用它也不愿使用 Hibernate。但正如您所说,抽象出各种数据库实例的大部分特性是使用 Hibernate 的一大好处。
    猜你喜欢
    • 1970-01-01
    • 2012-04-21
    • 2015-01-07
    • 1970-01-01
    • 2022-01-23
    • 1970-01-01
    • 2019-04-19
    • 1970-01-01
    相关资源
    最近更新 更多