Java 使用 Hibernate/Spring 生成数据库更新脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19942217/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:43:53  来源:igfitidea点击:

Generate a database update scripts with Hibernate/Spring

javaspringhibernatejpaliquibase

提问by tibo

I have a project where we use to rely on hibernate to update database with changes (hibernate.hbm2ddl.auto=update)... even on prod... I am migrating that to use liquibase instead.

我有一个项目,我们过去常常依赖 hibernate 来更新数据库的更改(hibernate.hbm2ddl.auto=update)...即使在 prod 上...我正在迁移它以使用 liquibase。

My only concern is that not everyone is a sql guru in my team, so I am looking for a simple way to generate the sql script that hibernate would have done if it was updating the database.

我唯一担心的是,并不是每个人都是我团队中的 sql 大师,所以我正在寻找一种简单的方法来生成 sql 脚本,如果它更新数据库,hibernate 会这样做。

We are all using Intellij IDEA but couldn't find this feature.

我们都在使用 Intellij IDEA,但找不到此功能。

Do you know any tool capable of doing that?

你知道有什么工具可以做到这一点吗?

Thank you

谢谢

回答by Andrei I

Well, I don't know an extremely easy solution, but may be the following will help you:

好吧,我不知道一个非常简单的解决方案,但可能以下内容会对您有所帮助:

on your local machines enable your logging lib to show the DDL queries. For example take a look here for an exampleand here for hibernate log categories.

在本地机器上启用日志库以显示 DDL 查询。例如,看看这里的一个例子这里的休眠日志类别

After saving all changes to your local DB (with hibernate.hbm2ddl.auto=update) you will have wanted output. On production use hibernate.hbm2ddl.auto=validate.

将所有更改保存到本地数据库(使用hibernate.hbm2ddl.auto=update)后,您将需要输出。在生产中使用hibernate.hbm2ddl.auto=validate

Eventually you might consider doing that on a special instance of server, with all DDL logging data saved in a special file.

最终,您可能会考虑在一个特殊的服务器实例上执行此操作,并将所有 DDL 日志记录数据保存在一个特殊文件中。

Also you could check, whether hibernate puts the update queries when hibernate.hbm2ddl.auto=validate.

您也可以检查,hibernate 是否在hibernate.hbm2ddl.auto=validate.

回答by frandevel

Please have a look at the following article:

请查看以下文章:

Schema generation script from Hibernate

来自 Hibernate 的模式生成脚本

It's a bit old, but adjusted a bit should do the trick:

它有点旧,但稍微调整一下应该可以解决问题:

  • Replace "create" with "update" in the configuration object
  • Adjust the base package name of your domain
  • Only generate it with the dialect you need. In the example three dialects are used for Oracle, MySQL and HSQL.
  • 将配置对象中的“create”替换为“update”
  • 调整域的基本包名称
  • 仅使用您需要的方言生成它。在示例中,三种方言用于 Oracle、MySQL 和 HSQL。

Good luck

祝你好运

回答by gavenkoa

Full schema dumped with mvn hibernate4:exportand pom.xml:

使用mvn hibernate4:export和转储的完整模式pom.xml

<!-- To export full DDL schema as it seeing by Hibernate run: mvn hibernate4:export -->
<plugin>
    <!-- http://mydevnotes.nicus.it/2013/03/generate-ddl-with-maven-jpa-hibernate-4.html -->
    <groupId>de.juplo</groupId>
    <artifactId>hibernate4-maven-plugin</artifactId>
    <version>1.1.0</version>
    <configuration>
        <hibernateDialect>org.hibernate.dialect.MySQLDialect</hibernateDialect>
        <delimiter>;</delimiter>
        <target>SCRIPT</target>
        <outputFile>${project.build.directory}/schema-hibernate4-maven-plugin.sql</outputFile>
    </configuration>
</plugin>

You may copy necessary parts.

您可以复制必要的部分。

With LiquiBase you have more options by generating diff between DB and Hibernate mapping file / annotations by mvn liquibase:diffand corresponding part in pom.xml:

使用 LiquiBase,您可以通过在 DB 和 Hibernate 映射文件/注释之间生成差异mvn liquibase:diff以及相应的部分来获得更多选择pom.xml

<plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>${liquibase.version}</version>
    <configuration>
        <changeLogFile>${basedir}/src/main/resources/sql/master.xml</changeLogFile>
        <propertyFile>${liquibase.profile}</propertyFile>
        <promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
        <logging>debug</logging>
        <outputFileEncoding>utf-8</outputFileEncoding>
        <driver>com.mysql.jdbc.Driver</driver>
        <!-- <url>jdbc:mysql://localhost:3306/app?autoReconnect=true&amp;characterEncoding=utf-8</url> -->
        <!-- <username>AAAAAA</username> -->
        <!-- <password>BBBBBB</password> -->
        <defaultSchemaName>testx</defaultSchemaName>
        <changelogSchemaName>testx</changelogSchemaName>

        <!-- For mvn liquibase:updateSQL -->
        <migrationSqlOutputFile>migration.sql</migrationSqlOutputFile>

        <referenceUrl>hibernate:spring:com.app.domain?dialect=org.hibernate.dialect.MySQLDialect</referenceUrl>
        <diffChangeLogFile>changelogDiff.xml</diffChangeLogFile>
        <diffTypes>tables,views,columns,indexes,foreignkeys,primarykeys,uniqueconstraints</diffTypes>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.springframework.data</groupId>
            <artifactId>spring-data-jpa</artifactId>
            <version>${spring-data.version}</version>
        </dependency>
        <!-- https://github.com/liquibase/liquibase-hibernate/wiki -->
        <dependency>
            <groupId>org.liquibase.ext</groupId>
            <artifactId>liquibase-hibernate4.2</artifactId>
            <version>3.5</version>
        </dependency>
    </dependencies>
</plugin>

You may read my notes about http://tips.defun.work/liquibase.html

你可以阅读我关于http://tips.defun.work/liquibase.html 的笔记

回答by darrachequesne

To actually display the scripts generated by Hibernate from your mappings, you can:

要从映射中实际显示 Hibernate 生成的脚本,您可以:

  • as suggested by Andrei I, add those two lines to your application.properties:

    spring.jpa.hibernate.ddl-auto=validate
    logging.level.org.hibernate.tool.hbm2ddl=DEBUG
    
  • 按照 Andrei I 的建议,将这两行添加到您的 application.properties 中:

    spring.jpa.hibernate.ddl-auto=validate
    logging.level.org.hibernate.tool.hbm2ddl=DEBUG
    

Source for Hibernate 4.3: SchemaUpdate.java

Hibernate 4.3 的来源:SchemaUpdate.java

  • or manually generate those scripts with the following code:

    LocalSessionFactoryBuilder sessionFactory = new LocalSessionFactoryBuilder(dataSource);
    sessionFactory.scanPackages("your.package.containing.entities");
    Dialect dialect = new MySQL5Dialect(); // select your dialect
    DatabaseMetadata metadata = new DatabaseMetadata(dataSource.getConnection(), dialect, sessionFactory);
    List<SchemaUpdateScript> scripts = sessionFactory.generateSchemaUpdateScriptList(dialect, metadata);
    
    Formatter formatter = FormatStyle.DDL.getFormatter();
    for (SchemaUpdateScript script : scripts) {
       System.err.println(formatter.format(script.getScript()) + ";");
    }
    
  • 或使用以下代码手动生成这些脚本:

    LocalSessionFactoryBuilder sessionFactory = new LocalSessionFactoryBuilder(dataSource);
    sessionFactory.scanPackages("your.package.containing.entities");
    Dialect dialect = new MySQL5Dialect(); // select your dialect
    DatabaseMetadata metadata = new DatabaseMetadata(dataSource.getConnection(), dialect, sessionFactory);
    List<SchemaUpdateScript> scripts = sessionFactory.generateSchemaUpdateScriptList(dialect, metadata);
    
    Formatter formatter = FormatStyle.DDL.getFormatter();
    for (SchemaUpdateScript script : scripts) {
       System.err.println(formatter.format(script.getScript()) + ";");
    }
    

You can even add this code in a @Test, as described here.

你甚至可以在@Test添加此代码,描述在这里

Good luck!

祝你好运!