[SPRING] 사용자 정의 구분 기호를 사용하여 봄 부팅으로 DDL 생성
SPRING사용자 정의 구분 기호를 사용하여 봄 부팅으로 DDL 생성
JPA - Hibernate 5.0.11과 함께 봄 부팅 v1.4.3을 사용하여 ddl 스크립트 생성 및 삭제를 생성하고 싶습니다.
대부분의 답변은 javax.persistence.schema 생성 속성을 사용합니다. 예 : https://stackoverflow.com/a/36966419/974186
이 방법의 문제점은 구분 기호없이 SQL 문을 출력한다는 것입니다. 예 :
create table ... (...)
create table ... (...)
구분 기호를 사용하여 명령문을 출력하고 싶습니다.
create table ... (...);
create table ... (...);
하지만 javax.persistence.schema-generation 속성을 찾을 수 없습니다.
그래서 당신이 구분 기호 속성을 설정할 수 있기 때문에 최대 절전 모드에서 SchemaExport를 사용하려고 생각했습니다. 하지만 SchemaExport를 만들려면 MetadataImplementor (비 deprected api)가 필요합니다.
스프링 부트에서 MetadataImplementor를 얻는 방법을 알아낼 수 없습니다.
누구든지 알 수 있습니까?
다음은 함께 연주 할 수있는 코드입니다.
@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>
최대 절전 모드 5.0
난 그냥 최대 절전 모드 5.0.11과 위의 코드를 시도. 최종. 네가 변해야 만하는 것은
SchemaExport schemaExport = new SchemaExport((MetadataImplementor) metadata);
schemaExport.setDelimiter(";");
schemaExport.setFormat(false);
schemaExport.setOutputFile(dropAndCreateDdlFile.getAbsolutePath());
schemaExport.execute(true, false, false, false);
또는 물론 자바 설정이 Metadata 대신 MetadataImplementor를 반환하고 ApplicationRunner 생성자 param을 변경하도록 할 수 있습니다.
해결법
-
==============================
1.마지막으로 많은 조사가 끝나면 공개 API를 사용하는 쉬운 솔루션을 발견했다고 생각합니다. 내가 찾은 해결책은 최대 절전 모드 5.2 (더 구체적인 5.2.6. 최종)를 사용합니다. 그러나 나는 또한 5.0에 적용될 수 있다고 생각한다.
마지막으로 많은 조사가 끝나면 공개 API를 사용하는 쉬운 솔루션을 발견했다고 생각합니다. 내가 찾은 해결책은 최대 절전 모드 5.2 (더 구체적인 5.2.6. 최종)를 사용합니다. 그러나 나는 또한 5.0에 적용될 수 있다고 생각한다.
여기 내 스프링 자바 구성입니다
@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 구성은 Metadata Bean을 작성합니다. 이 빈은 스키마 생성을 실행하기 위해 hibernate 5.2에서 사용될 수있다. 예 :
@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 dialect는 spring boot application.properties를 사용하여 설정된다. 나의 경우에는:
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL57InnoDBDialect
-
==============================
2.내가 알게 된 것은 sessionFactory가 createSQL, dropSQL, outputFile 및 delimiter와 같은 schemaExport 값을 보유한다는 것입니다.
내가 알게 된 것은 sessionFactory가 createSQL, dropSQL, outputFile 및 delimiter와 같은 schemaExport 값을 보유한다는 것입니다.
Bean으로서의 sessionFactory는 이와 같이 생성 될 수 있고 autowiring을 위해 사용할 수 있습니다 :
.... @Autowired private EntityManagerFactory entityManagerFactory; @Bean public SessionFactory sessionFactory() { if (entityManagerFactory.unwrap(SessionFactory.class) == null) { throw new NullPointerException("factory is not a hibernate factory"); } return entityManagerFactory.unwrap(SessionFactory.class); }
이것은 작동하는 해결책은 아니지만 sessionFactory를 사용하여 schemaExport를 수동으로 구성하는 데 도움이 될 수 있습니다. 나는 단지 속성을 사용하고 거기에 구분 기호를 설정하기위한 해결책을 찾지 못한다. 그러나 작업 솔루션을 찾는 데 약간의 도우미가 될 수 있습니다.
보다 유용한 정보를 찾으면 답을 업데이트 할 것입니다.
-
==============================
3.그것은 아마도 해결 방법이지만 내 경우에는 프로젝트를 빌드하는 동안 세미콜론을 추가하는 것으로 충분합니다. Maven 플러그인을 사용하여이를 수행 할 수 있습니다 (예 :
그것은 아마도 해결 방법이지만 내 경우에는 프로젝트를 빌드하는 동안 세미콜론을 추가하는 것으로 충분합니다. Maven 플러그인을 사용하여이를 수행 할 수 있습니다 (예 :
<plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.6.0</version> <executions> <execution> <id>add-semicolon-to-sql-file</id> <phase>generate-resources</phase> <goals> <goal>exec</goal> </goals> <configuration> <executable>sed</executable> <arguments> <argument>-i</argument> <argument>/;$/!s/$/;/</argument> <argument>src/main/resources/db/migration/V1__init.sql</argument> </arguments> </configuration> </execution> </executions> </plugin>
-
==============================
4.René에서 스프링 부트 2에서 작동하도록 솔루션을 수정했습니다. 버전 2.0.4로 테스트되었습니다.
René에서 스프링 부트 2에서 작동하도록 솔루션을 수정했습니다. 버전 2.0.4로 테스트되었습니다.
@Configuration @AutoConfigureAfter({ HibernateJpaAutoConfiguration.class }) public class HibernateMetadataBean { @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); } return metadataSources.buildMetadata(); } @ConditionalOnMissingBean({ StandardServiceRegistry.class }) @Bean public StandardServiceRegistry getStandardServiceRegistry(JpaProperties jpaProperties) { StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder(); Map<String, String> properties = jpaProperties.getProperties(); ssrb.applySettings(properties); return ssrb.build(); } @ConditionalOnMissingBean({ PersistenceUnitInfo.class }) @Bean public PersistenceUnitInfo getPersistenceUnitInfo(BeanFactory beanFactory) { List<String> packagesToScan = EntityScanPackages.get(beanFactory).getPackageNames(); if (packagesToScan.isEmpty() && AutoConfigurationPackages.has(beanFactory)) { packagesToScan = AutoConfigurationPackages.get(beanFactory); } DefaultPersistenceUnitManager persistenceUnitManager = new DefaultPersistenceUnitManager(); String[] packagesToScanArr = StringUtils.toStringArray(packagesToScan); persistenceUnitManager.setPackagesToScan(packagesToScanArr); persistenceUnitManager.afterPropertiesSet(); return persistenceUnitManager.obtainDefaultPersistenceUnitInfo(); } }
-
==============================
5.당신은 다음의 Hibernate 속성을 설정하려고 시도 할 수있다.
당신은 다음의 Hibernate 속성을 설정하려고 시도 할 수있다.
spring.jpa.properties.hibernate.hbm2ddl.delimiter=; #in addition to the other standard JPA properties you refered to, namely: spring.jpa.properties.javax.persistence.schema-generation.scripts.action=create spring.jpa.properties.javax.persistence.schema-generation.scripts.create-target=create.sql
이 기능은 Spring Boot 2.1.2.RELEASE +에서 Hibernate 버전 (5.3.7.Final) 프로젝트와 동일한 기능을 필요로하는 곳에서 작업하는 것으로 나타났습니다.
그것은 당신의별로 다르지 않은 Hibernate 환경에서 잘 작동 할 것입니다.
주제가 약간 벗어나지 만, 내가 가지고있는 한가지 문제 : Hibernate는 create.sql에 추가합니다. 파일 내용을 바꿀 수있는 방법을 찾았습니다.
from https://stackoverflow.com/questions/41832183/generate-ddl-with-spring-boot-using-a-custom-delimiter by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] JSP / 서블릿 속성 파일에서 매개 변수를 읽으십시오? (0) | 2019.03.22 |
---|---|
[SPRING] POST 데이터를 기록하는 RestTemplate (0) | 2019.03.22 |
[SPRING] json 응답에서 필드를 동적으로 제거하는 방법은 무엇입니까? (0) | 2019.03.22 |
[SPRING] 스프링 데이터 JPA와 1 대 1 관계 유지 (0) | 2019.03.22 |
[SPRING] 모든 데이터베이스 쿼리에 대한 전역 최대 절전 모드 필터 (0) | 2019.03.22 |