Spring Boot 如何使用现代的Sping Boot + Data JPA和Hibernate设置生成一个ddl创建脚本?

ukdjmx9f  于 2022-11-05  发布在  Spring
关注(0)|答案(4)|浏览(207)

目前,我使用的是默认的@SpringBootApplication注解,它在application.properties中具有以下属性:

spring.datasource.url=jdbc:mysql://localhost/dbname
spring.datasource.username=X
spring.datasource.password=X
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.jpa.hibernate.naming_strategy=my.package.CustomNamingStrategy

从JPA2.1开始,我应该能够使用javax.persistence.schema-generation.*属性,但是在我的www.example.com中设置它们application.properties似乎没有效果。
我看到过like this的例子,它们连接了一大堆额外的bean,但是它们没有使用Mysql。无论如何,这样做需要我配置许多选项,现在Spring正在为我处理这些选项。
我的目标是:

  • 使用MYSQL方言生成模式创建sql脚本
  • 而不需要数据库连接
  • 在build目录中输出脚本
  • 另外,生成休眠envers表将是一个巨大的优势。

我可不愿意:

  • 在活动数据库上创建/删除方案

库版本:

hibernate          : 4.3.11.FINAL
   spring framework   : 4.2.5.RELEASE
   spring-boot        : 1.3.3.RELEASE
   spring-data-jpa    : 1.10.1.RELEASE   // for  querydsl 4 support
   spring-data-commons: 1.12.1.RELEASE   // for  querydsl 4 support

(使用Gradle,而非Maven)

dbf7pr2w

dbf7pr2w1#

啊,就在我发布这个问题之后,一部分Spring Data 文档吸引了我的注意:
73.5配置JPA属性此外,在创建本地EntityManagerFactory时,spring.jpa.properties.* 中的所有属性都将作为普通JPA属性(去掉前缀)传递。
所以,来回答我自己的问题:请在javax.persistence属性前面加上spring.jpa.properties:

spring.jpa.properties.javax.persistence.schema-generation.create-source=metadata
spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create
spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql

完成此操作后,将在项目根目录中自动生成架构文件。

2hh7jdfx

2hh7jdfx2#

这是特定于yml的配置,用于使spring Boot 在根文件夹中生成ddl创建脚本:

spring:
  jpa:
    properties:
      javax:
        persistence:
          schema-generation:
            create-source: metadata
            scripts:
              action: create
              create-target: create.sql
lstz6jyr

lstz6jyr3#

更新您的jpa properties将为您生成脚本。

<prop key="javax.persistence.schema-generation.scripts.action">drop-and-create</prop>
            <prop key="javax.persistence.schema-generation.scripts.create-target">./create_mssql.sql</prop>
            <prop key="javax.persistence.schema-generation.scripts.drop-target">./drop_mssql.sql</prop>

这将在给定位置生成脚本。还有其他属性可用于各种用例,请参阅here
整个配置如下所示

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
  <persistence-unit name="my-persistence-unit" transaction-type="JTA">
    <description>Forge Persistence Unit</description>
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:jboss/datasources/ExampleDS</jta-data-source>
    <exclude-unlisted-classes>false</exclude-unlisted-classes>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect"/>

      <property name="javax.persistence.schema-generation.database.action" value="drop-and-create"/>
      <property name="javax.persistence.sql-load-script-source" value="META-INF/data.sql"/>
    </properties>
  </persistence-unit>
</persistence>
u59ebvdq

u59ebvdq4#

下面的代码将允许您以独立的方式(独立于Sping Boot )为所有发现的实体生成DDL。这允许您在不必启动主应用程序的情况下生成架构。
它使用下列相依性:

  • org.reflections:reflections
  • org.reflections:reflections
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import org.hibernate.tool.schema.TargetType;
import org.reflections.Reflections;
import org.reflections.util.ConfigurationBuilder;

import javax.persistence.Entity;
import java.util.EnumSet;
import java.util.Set;

public class SchemaGenerator {
    public static void main(String... args) {
        new SchemaGenerator().generateSchema();
    }

    private void generateSchema() {
        var serviceRegistry = new StandardServiceRegistryBuilder()
                .applySetting("hibernate.dialect", "<fully qualifified dialect class name>")
                .build();
        var entities = scanForEntities("<package1>", "<package2>");
        MetadataSources metadataSources = new MetadataSources(serviceRegistry);
        entities.forEach(metadataSources::addAnnotatedClass);
        Metadata metadata = metadataSources.buildMetadata();
        SchemaExport schemaExport = new SchemaExport();
        schemaExport.setFormat(true);
        schemaExport.setOutputFile("<output file name>");
        schemaExport.createOnly(EnumSet.of(TargetType.SCRIPT), metadata);
    }

    private Set<Class<?>> scanForEntities(String... packages) {
        var reflections = new Reflections(
                new ConfigurationBuilder()
                        .forPackages(packages)
        );
       return reflections.getTypesAnnotatedWith(Entity.class);
    }
}

相关问题