java Spring boot 和 Hibernate:打印/日志 DDL

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/25048199/
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-11-02 07:12:53  来源:igfitidea点击:

Spring boot and Hibernate: print/log DDL

javaspringhibernatejpaspring-boot

提问by bertvh

After I've added one or more classes with database mappings (JPA/hibernate), I would like Hibernate to print out the necessary schema updates so I can execute them on the database (through FlyWay for example). I do not want the updates to be executed automatically.

在我添加了一个或多个具有数据库映射(JPA/hibernate)的类之后,我希望 Hibernate 打印出必要的模式更新,以便我可以在数据库上执行它们(例如通过 FlyWay)。我不希望自动执行更新。

The only property that seems to give some control over this is the following

似乎可以对此进行一些控制的唯一属性如下

org.hibernate.tool.hbm2ddl=validate|update|create|create-drop|none

I don't want to update/change anything automatically. I want to set this to validate or none. When I do this, I don't get to see the generated schema.

我不想自动更新/更改任何内容。我想将此设置为验证或无。当我这样做时,我看不到生成的模式。

I classical spring application, I used to use the hibernate SchemaExportclass to print the DDL.

我是经典的 spring 应用程序,我曾经使用 hibernateSchemaExport类来打印 DDL。

SchemaExport schemaExport = new SchemaExport(cfg);
schemaExport.execute(true, false, false, false);

Is there anything similar I can use in Spring Boot?

我可以在 Spring Boot 中使用类似的东西吗?

回答by Chris Savory

This is what I do...

这就是我所做的...

First I make my entity changes, then I set these to:

首先,我对实体进行更改,然后将这些设置为:

spring.jpa.show-sql=true
spring.jpa.hibernate.ddl-auto=update

Then

然后

  1. re-run my app and let hibernate make the changes to the database.
  2. Go into the logs and copy the sql that hibernate used to update the db
  3. Paste that sql into a new Flyway script
  4. Shudown Boot App
  5. Drop the local database
  6. change ddl-auto back to validate
  7. Restart Boot App
  8. Test to make sure that Flyway made the correct updates. Hibernate and Flyway will now be in sync.
  1. 重新运行我的应用程序并让 hibernate 对数据库进行更改。
  2. 进入日志并复制hibernate用于更新数据库的sql
  3. 将该 sql 粘贴到新的 Flyway 脚本中
  4. 关闭启动应用程序
  5. 删除本地数据库
  6. 将 ddl-auto 改回验证
  7. 重新启动启动应用程序
  8. 测试以确保 Flyway 进行了正确的更新。Hibernate 和 Flyway 现在将同步。

回答by FrancescoM

The solution of setting the show-sql didn't work for me even with debug turned on, so i ended up writing and running this simple class.

即使打开调试,设置 show-sql 的解决方案对我也不起作用,所以我最终编写并运行了这个简单的类。

public class SchemaExporter{

public static org.hibernate.cfg.Configuration getConfiguration() {
    org.hibernate.cfg.Configuration cfg = new org.hibernate.cfg.Configuration();
    ClassPathScanningCandidateComponentProvider scanner = new ClassPathScanningCandidateComponentProvider(false);
    scanner.addIncludeFilter(new AnnotationTypeFilter(Entity.class));
    for (BeanDefinition bd : scanner.findCandidateComponents("com.package.where.my.entitybeans.are")) {
        String name = bd.getBeanClassName();
        try {
            System.out.println("Added annotated entity class " + bd.getBeanClassName());
            cfg.addAnnotatedClass(Class.forName(name));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    cfg.setProperty("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
    cfg.setProperty("hibernate.show_sql", "true");
    cfg.setProperty("hibernate.format_sql", "true");
    cfg.setProperty("hibernate.hbm2ddl.auto", "update");
    cfg.setProperty("hibernate.ejb.naming_strategy", "org.hibernate.cfg.ImprovedNamingStrategy");

    cfg.setProperty("hibernate.connection.url", CONNECTIONURL);
    cfg.setProperty("hibernate.connection.username", USERNAME);
    cfg.setProperty("hibernate.connection.password", PWD);
    cfg.setProperty("hibernate.connection.driver", DRIVER);
    return cfg;
}

public static void main(String[] args) {
    SchemaExport export = new SchemaExport(getConfiguration());
    export.setDelimiter(";");
    export.setHaltOnError(true);
    export.setFormat(true);
    export.create(true,true);
}

}

Running it i can see the DDL in the console and continue as Chris suggested

运行它我可以在控制台中看到 DDL 并按照 Chris 的建议继续