【问题标题】:How to dynamically add Entity in Hibernate?如何在 Hibernate 中动态添加实体?
【发布时间】:2023-04-02 07:40:01
【问题描述】:

我是一名 Java 开发人员。我正在使用spring 4.0.1hibernate 4.2.21。我有一堂课如下:

@Entity
@Inheritance(...)
public abstract class Feature{
   @Id
   @GeneratedValue
   protected Long id;

   ...

}

现在我有很多类如下:

Label.java 类:

@Entity
public class Label extends Feature{
   protected String str;

   ...
}

Point.java 类:

@Entity
public class Point extends Feature{
   protected Integer intg;

   ...
}

我有 20 多个从 Feature 类扩展的实体类。有什么方法可以在不编写硬代码的情况下将这些类(例如LabelPoint)动态添加到项目中?

更新

例如,Hibernate 从数据库中获取数据,然后根据这些数据,创建模型。

  1. 有可能吗?
  2. 我该怎么办?

【问题讨论】:

  • 尝试以更好的方式描述您的问题?如果我明白你在说什么,你可以在你的 ide 中使用 jpa 工具自动生成所有实体
  • There is a way to add dynamically this classes(such as Label and Point) to the project without writing hard code? 是什么意思我想现在你应该熟悉如何提问了!
  • 我有 20 多个从 Feature 扩展的实体。我想在项目部署时自动生成所有这些类。
  • 关于你的更新:请看看我的回答 :-) 有一个工具可以从数据库结构创建实体
  • @mortezamalvandi :您是否尝试过我在回答中提到的?结果如何?

标签: java hibernate spring-mvc datapersistance


【解决方案1】:

您可以尝试收集构建模型所需的数据并为每个实体生成一个休眠hbm.xml 文件(是xml格式,在读取您在更新中描述的所需数据后易于使用java生成)

之后,您可以在 http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html#configuration-programmatic 之后以编程方式创建一个休眠配置对象

我认为,如果我能很好地理解您的问题,您可以通过这种方法实现您想要的。

【讨论】:

    【解决方案2】:

    我认为它不是一个需要动态更改的好的数据库设计。这听起来冗长且不一致。再次观察您的域并尝试设计一个不会在运行时更改的适当实体关系。

    【讨论】:

      【解决方案3】:

      我认为你想在运行时生成你的实体类,而不是你必须编写你的 java 文件并编译它等等。 如果这是您的要求,您可以使用像 javassist 这样的字节码生成器在运行时生成和注释您的类文件。然后,您可以使用 JPA、Hibernate 和任何其他 ORM 框架将其持久化到您的表中。

      【讨论】:

      【解决方案4】:

      据我了解,您需要开发一个工具,收集与Feature 表具有一对一关系的表名。

      我的建议是这样的(用Oracle测试过):

      1) 从您的数据库中,获取引用您的功能表的表元数据。 下面将打印与您的表有外键关系的标签、点等表。
      如果您只想生成一个子集(不相关的表也可能有这种关系),您可能会放一个 common 外键列名,并借助此类标记过滤掉不相关的表。

      Connection connection = jdbcTemplate.getDataSource().getConnection();
      DatabaseMetaData metaData = connection.getMetaData();
      
      ResultSet exportedKeys = metaData.getExportedKeys(connection.getCatalog(), "<your_schema_name>", "FEATURE");
      while (exportedKeys.next()){
          String fkTableName = exportedKeys.getString("FKTABLE_NAME");
          String fkColumnName = exportedKeys.getString("FKCOLUMN_NAME");  
          System.out.println("[fkTableName:" + fkTableName + "], [fkColumnName" + fkColumnName + "]");
      }
      exportedKeys.close();
      


      2)对于上面收集的表,对于我们关注的每个表,获取类型和列的表元数据。

      ResultSet columns = metaData.getColumns(connection.getCatalog(), "<your_schema_name>", "<your_table_name>", null);
      while (columns.next()){
          String columnName = columns.getString("COLUMN_NAME");
          String typeName = columns.getString("TYPE_NAME");
          System.out.println("[columnName:" + columnName + "], [typeName" + typeName + "]");
      }
      columns.close();
      


      3) 根据 2 的结果生成您的 Java 类。使用字段、getter setter、注释等。然后将它们复制到您的源目录中。你知道其余的:)

      希望这会有所帮助。

      【讨论】:

      • 这是一个好主意,但在第三步生成 java 类不足以在运行时持久化对象。您需要编译生成的源文件才能使用它们。
      【解决方案5】:

      我认为您可以使用 Hibernate 逆向工程为所有数据库表生成实体。请参考this链接。这将逐步解释使用hibernate逆向工程从数据库生成实体的过程。

      【讨论】:

        【解决方案6】:

        不要重复自己。

        如果您真的需要这些类,请使用 IDE(如 eclipse)来生成这些类。或者使用泛型和继承来创建一个既能存储字符串又能存储整数的类。

        但如果您实际上需要类,请生成 SQL(不是 JPQL 或 HQL)并将数据存储在 java.util.Map 和类似的数据结构中。

        课程适合:

        • 类型安全
        • 将逻辑(方法)与数据(字段)相结合
        • 描述关系

        在您的情况下,您可能只需要:

        • 在运行时存储结构化数据。

        【讨论】:

          【解决方案7】:

          我认为您可以使用 eclipse 来做到这一点,但必须或多或少地修改类以保留继承层次结构。

          • 右击项目名称并选择Properties
          • 如果未启用项目构面,则使用项目构面

          • 如果未选中JPA,请单击它,然后单击确定关闭项目属性窗口。

          • 在项目属性中启用 JPA 后,现在再次右键单击 eclipse 项目名称,您应该会看到一个新的上下文菜单项 JPA 工具 出现。选择从表中生成实体

          选择一个数据库连接让Eclipse获取用来生成的表 类从。

          这里是how to setup db in eclipse

          • 最好使用上述方法在虚拟项目中创建实体,并将实体类复制到真实项目中。

          • Eclipse 的类重构可用于保留所需的继承层次结构。

          希望这会有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-08-22
            • 1970-01-01
            • 1970-01-01
            • 2012-01-16
            • 1970-01-01
            相关资源
            最近更新 更多