我想使用Spring Boot v1.4.3和JPA-Hibernate 5.0.11生成create和drop ddl脚本。
我发现的大多数答案都使用这些javax.persistence.schema-generation属性。
javax.persistence.schema-generation
这种方法的问题是它输出不带分隔符的sql语句。例如
create table ... (...) create table ... (...)
我希望它输出带有定界符的语句 ;
;
create table ... (...); create table ... (...);
但是我找不到任何javax.persistence.schema-generation属性来配置它。
因此,我想使用SchemaExportfromhibernate模式,因为您可以设置delimiter属性。但是要创建一个,SchemaExport我需要一个MetadataImplementor(不受影响的api)。
SchemaExport
MetadataImplementor
我不知道如何MetadataImplementor从Spring Boot。
有谁知道是否有
这是一些您可以使用的代码
@SpringBootApplication @ComponentScan(basePackageClasses = Application.class) @EntityScan(basePackageClasses = User.class) public class Application { @Bean public ApplicationRunner getApplicationRunner() { return new ApplicationRunner() { public void run(ApplicationArguments args) throws Exception { // MetadataImplementor metadataImplementor = ???; // new SchemaExport(metadataImplementor); } }; } public static void main(String[] args) { SpringApplication application = new SpringApplication(Application.class); application.run(args); } }
@Entity public class User { @Id @GeneratedValue private Long id; private String name; public Long getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
@Entity public class Person { @Id @GeneratedValue private Long id; private String name; public Long getId() { return id; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
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
<properties> <spring.boot.version>1.4.3.RELEASE</spring.boot.version> </properties> <dependencyManagement> <dependencies> <dependency> <!-- Import dependency management from Spring Boot --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring.boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> </dependency> </dependencies>
使用Hibernate 5.0
我只是用hibernate尝试了上面的代码5.0.11.Final。您唯一需要更改的是
5.0.11.Final
SchemaExport schemaExport = new SchemaExport((MetadataImplementor) metadata); schemaExport.setDelimiter(";"); schemaExport.setFormat(false); schemaExport.setOutputFile(dropAndCreateDdlFile.getAbsolutePath()); schemaExport.execute(true, false, false, false);
或者当然让Java配置返回MetadataImplementor而不是Metadata并更改ApplicationRunner构造函数参数。
Metadata
ApplicationRunner
最后,经过大量调查,我认为我找到了一个使用公共API的简单解决方案。我发现的解决方案使用hibernate5.2(更具体5.2.6.Final)。但我认为它也可以适应5.0
5.2
5.2.6.Final
5.0
这是我的Spring Java配置
@Configuration @AutoConfigureAfter({ HibernateJpaAutoConfiguration.class }) public class HibernateJavaConfig { @ConditionalOnMissingBean({ Metadata.class }) @Bean public Metadata getMetadata(StandardServiceRegistry standardServiceRegistry, PersistenceUnitInfo persistenceUnitInfo) { MetadataSources metadataSources = new MetadataSources(standardServiceRegistry); List<String> managedClassNames = persistenceUnitInfo.getManagedClassNames(); for (String managedClassName : managedClassNames) { metadataSources.addAnnotatedClassName(managedClassName); } Metadata metadata = metadataSources.buildMetadata(); return metadata; } @ConditionalOnMissingBean({ StandardServiceRegistry.class }) @Bean public StandardServiceRegistry getStandardServiceRegistry(JpaProperties jpaProperties) { StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder(); Map<String, String> properties = jpaProperties.getProperties(); ssrb.applySettings(properties); StandardServiceRegistry ssr = ssrb.build(); return ssr; } @ConditionalOnMissingBean({ PersistenceUnitInfo.class }) @Bean public PersistenceUnitInfo getPersistenceUnitInfo(EntityScanPackages entityScanPackages) { List<String> packagesToScan = entityScanPackages.getPackageNames(); DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager(); String[] packagesToScanArr = (String[]) packagesToScan.toArray(new String[packagesToScan.size()]); persistenceUnitManager.setPackagesToScan(packagesToScanArr); persistenceUnitManager.afterPropertiesSet(); PersistenceUnitInfo persistenceUnitInfo = persistenceUnitManager.obtainDefaultPersistenceUnitInfo(); return persistenceUnitInfo; } }
Java配置创建一个Metadatabean。可以在hibernate 5.2中使用此bean执行模式生成。例如
@Component public class GenerateDDLApplicationRunner implements ApplicationRunner { private Metadata metadata; public GenerateDDLApplicationRunner(Metadata metadata) { this.metadata = metadata; } public void run(ApplicationArguments args) throws Exception { File dropAndCreateDdlFile = new File("drop-and-create.ddl"); deleteFileIfExists(dropAndCreateDdlFile); SchemaExport schemaExport = new SchemaExport(); schemaExport.setDelimiter(";"); schemaExport.setFormat(false); schemaExport.setOutputFile(dropAndCreateDdlFile.getAbsolutePath()); schemaExport.execute(EnumSet.of(TargetType.SCRIPT), Action.BOTH, metadata); } private void deleteFileIfExists(File dropAndCreateDdlFile) { if (dropAndCreateDdlFile.exists()) { if (!dropAndCreateDdlFile.isFile()) { String msg = MessageFormat.format("File is not a normal file {0}", dropAndCreateDdlFile); throw new IllegalStateException(msg); } if (!dropAndCreateDdlFile.delete()) { String msg = MessageFormat.format("Unable to delete file {0}", dropAndCreateDdlFile); throw new IllegalStateException(msg); } } } }
hibernate方言是使用spring boot配置的application.properties。就我而言:
application.properties
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL57InnoDBDialect