【问题标题】:How to import initial data to database with Hibernate?如何使用 Hibernate 将初始数据导入数据库?
【发布时间】:2010-10-14 23:59:58
【问题描述】:

在部署应用程序时,我经常使用 Hibernate 的能力来创建数据库模式以简化部署。这很容易通过配置 hibernate.hbm2ddl.auto 属性来实现。

但是,有时我还需要向数据库中插入一些初始数据,例如 root 用户。有没有办法通过休眠和某种加载文本文件来实现这一点?

我知道我可以很容易地编写代码来实现这一点,但只是想知道是否已经有一些实用程序可以帮助我通过配置实现相同的目标?

【问题讨论】:

    标签: hibernate import initialization data-importer


    【解决方案1】:

    我通过搜索“休眠装置”找到了这个:

    Hibernate 将创建数据库 当实体管理器工厂是 创建(实际上当 Hibernate 的 SessionFactory 是由 实体管理器工厂)。如果一个文件 名为 import.sql 存在于 类路径('/import.sql') Hibernate 将执行 SQL 之后从文件中读取的语句 数据库模式的创建。 重要的是要记住 在 Hibernate 创建它的模式之前 清空它(删除所有表, 约束或任何其他数据库 将在其中创建的对象 构建模式的过程)。

    来源:http://www.velocityreviews.com/forums/t667849-hibernate-quotfixturesquot-or-database-population.html

    试一试,让我们知道它是否有效!

    【讨论】:

    • 据我所知,sql 似乎不是 db-agnostic
    • +!对于 import.sql 应该在根目录中,而不仅仅是在任何地方
    【解决方案2】:

    将 import.sql 添加到类路径效果很好,hbm2ddl 检查文件是否存在并执行它。唯一额外的细节是每个sql命令必须在自己的行中,否则会执行失败。

    这也只有在 hbm2ddl.auto 设置为 createcreate-drop 时才有效。

    【讨论】:

    • 仅当 hbm2ddl.auto 设置为“create”或“create-drop”时它也有效。
    • 这条评论对我很有帮助。
    • 将每个 sql 语句放在单独的行中的要求很奇怪。谢谢指出
    • 您可以通过将<property name="hibernate.hbm2ddl.import_files_sql_extractor">org.hibernate.tool.hbm2ddl.MultipleLinesSqlCommandExtractor</property> 添加到您的hibernate.cfg.xml (stackoverflow.com/a/15090964) 来启用多行sql 命令
    【解决方案3】:

    在您的休眠配置中添加休眠属性hibernate.hbm2ddl.import_files。 更改 hibernate.hbm2ddl.auto 属性以创建。 在 /classes 目录中添加 initial_data.sql 并使用初始 sql 代码插入数据。 Hibernate 在创建数据库模式后执行此操作。

    <bean id="sessionFactory"
        class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">create</prop>
                <prop key="hibernate.hbm2ddl.import_files">initial_data.sql</prop>
            </props>
        </property>
    </bean>
    

    如果您不想在 hibernate 配置中添加属性,您可以在 /classes 目录中创建文件 import.sql,如果属性 hibernate.hbm2ddl.auto 等于 create,则 hibernate 默认使用此文件

    【讨论】:

      【解决方案4】:

      为什么hbm2ddl.autohbm2ddl.import_files 属性是邪恶的

      (当被误用作数据库变更管理工具时)

      就像elsewhere 所说,使用hibernate.hbm2ddl.autohibernate.hbm2ddl.import_files 进行数据库变更管理有一些严重 的缺点:

      1. 只能更改结构。现有值可能会被覆盖,或者 - 在最坏的情况下 - 只是发送到 Nirvana。如果没有liquibasescriptella 之类的工具,您就没有任何ETL 功能。
      2. 此方法没有事务。结构和数据语句都将在事务管理器接管之前执行。假设您在 256 的第 42 条语句中有错误。您的数据库现在处于不一致的状态。
      3. 恕我直言,您失去了透明度和控制权:如果 scriptella 脚本或 liquibase 更改设置或通常与域模型中的更改一起提交,您在域模型中进行更改并希望(基本上)hibernate 会找出什么去做。 (事实并非如此,但那是另一回事。)
      4. 对于集成、系统和验收测试,您只需假设您的测试数据库与您的生产数据库处于绝对、完全相同的状态。你必须手动跟踪它(祝你好运,玩得开心!;))。万一你犯了一个错误,一个小小的失误就足够了,结果可能我们将是灾难性的。

      我个人使用 liquibase 进行数据库变更管理,并开发了以下工作流程来减少维护工作:

      即使对于必须实现customChange 的复杂更改,这也可以在几个小时内完成,包括回滚的定义、测试和文档。对于微不足道的更改,只需几分钟。基本上:您必须做更多的工作(我在不到一天的时间内为 4 个数据库配置创建了自定义更改集),但您可以放心,您已尽一切可能使数据库保持一致状态。

      【讨论】:

      • Liquibase 非常棒,对于一个已经确定并由团队开发的产品来说,这是一个绝妙的主意。另一方面,如果你是一个单独的开发者,构建一个原型,充实基础知识或者探索一些会非常频繁的东西,能够在几秒钟而不是几分钟或几小时内快速让它工作是非常有价值的。通常,一旦存在诸如 QA 数据集之类的东西,或者肯定在您拥有生产数据时,应该删除 hbm2ddl.auto。愚蠢地说任何一种方式都是邪恶的。
      • @Gus "没有什么比临时更确定的了" ;) 还有一些你似乎真的忽略了的东西 "(当被误用作数据库变更管理工具时)" 问题清楚地表明我们正在谈论部署,因此数据库更改管理是这里的上下文。我坚持我的说法:对于部署,两者都是彻头彻尾的邪恶。顺便说一句,即使作为单一开发人员,liquibase 也没有更多工作。从长远来看,它会更少。
      • 这很愚蠢而且毫无帮助。对于简单的自动化测试,hbm2ddl 对大多数人来说是一个完全合适的工具。
      • 那么,您如何确保您的生产设置将迁移到您的开发设置?开火祈祷?
      • 你把我写的一个有用的工具称为“邪恶”,数十万人已经成功使用了近二十年。它不是数据管理中每一个问题的万能解决方案,但这并不意味着它是“邪恶的”。
      【解决方案5】:

      经过几个小时的磕磕绊绊,我决定分享我的发现,尽管这是一篇很老的帖子。

      为了使其正常工作,我必须执行以下操作:

      • hbmddl 设置为 createcreate-drop
      • 类路径根目录中的file.sql;就我而言,我只是把它放在resources 文件夹中,我使用的是 maven。
      • 一行中的每个sql命令
      • 每个 file.sql 必须在文件开头有一个空行 ==> 不知道这个原因,但如果我不插入那个空行,在执行服务器告诉我第一个字符附近有语法错误。

      希望对您有所帮助。

      【讨论】:

      • “一线问题”听起来像 BOM
      • 我认为您的意思是 import.sql,而不是 file.sql。
      • “file.sql”是指任何 *.sql 文件,不管名称,只要您在持久性文件中指定它即可。 import.sql 是默认导入的文件名(如果存在),无需在持久化文件中指定。
      【解决方案6】:

      在 JPA 中执行此操作的标准方法是使用配置属性 javax.persistence.sql-load-script-source

      您可以探索与 Hibernate 的 AvailableSettings 类中列出的架构导出和测试数据导入相关的各种设置。

      【讨论】:

        【解决方案7】:

        请确保您的 import.sql 格式正确。从单行插入语句开始进行测试。

        【讨论】:

          猜你喜欢
          • 2012-09-12
          • 2020-10-21
          • 2014-11-20
          • 1970-01-01
          • 1970-01-01
          • 2014-10-25
          • 2020-09-24
          • 2019-11-14
          • 2013-07-01
          相关资源
          最近更新 更多