[英]Spring-Boot execute data.sql in one profile only
我有这个应用程序,它使用配置文件“默认”连接到 PostgreSQL 数据库并使用 Flyway 进行迁移。
我想创建另一个名为“devEmbeddedCreate”的配置文件,我需要在其中使用嵌入式数据库服务器(h2),在application.properties
文件中使用spring.jpa.hibernate.ddl-auto=create-drop
创建数据库并执行不同的调用“data.sql”脚本来初始化一些表。
如果我将脚本保留为“data.sql”文件名,则每次应用程序启动时都会执行它。 这是我不想发生的事情,我只需要在某个配置文件中执行它。
我尝试过的事情:
文档提到可以有一个schema-${platform}.sql
文件,您可以在配置中使用spring.datasource.platform
定义平台。 它不适用于data-${platform}.sql
文件的问题。 ( 这里)
创建了一个EmbeddedDatabaseBuilder
。 问题是当我使用它时,它不会自动创建数据库而只应用指定的脚本。 找不到像spring.jpa.hibernate.ddl-auto=create-drop
那样自动创建数据库的方法。 ( 这里和这里)
寻找一种将 XML 配置转换为基于 Java 的配置的方法,找到了一种创建数据库和所有内容的方法。 经过大量调整和更改以在内存中工作后,它看起来很有希望,但无法找出数据库在启动时关闭(并擦除其所有结构)的原因(此处)
必须有一种更简单的方法来说“嘿春天......当我的配置文件是devEmbeddedCreate
,运行这个data-devEmbeddedCreate.sql
脚本,对吧?
您的方法1) 走在正确的轨道上,但您应该通过spring.datasource.platform
而不是spring.jpa.database-platform
设置数据源spring.jpa.database-platform
。 脚本执行功能不是特定于 JPA 的。
您还可以通过设置spring.datasource.schema
属性手动指定执行哪些 SQL 脚本文件。 这是1.0.2.RELEASE 中 org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration 文件的摘录:
String schema = this.datasourceProperties.getProperty("schema");
if (schema == null) {
schema = "classpath*:schema-"
+ this.datasourceProperties.getProperty("platform", "all")
+ ".sql,classpath*:schema.sql,classpath*:data.sql";
}
如您所见,文档中指定的文件集仅在您未指定自己的列表时使用。
对于未来的读者。
我以稍微不同的方式解决了这个问题……使用“java config”。
下面最重要的部分是:
@Bean @Profile(SPRING_PROFILE_DEFAULT) public DataSourceInitializer getDataSourceInitializer(final DataSource dataSource) {
这将加载未命名为“data.sql”的 .sql 文件......仅当该配置文件处于活动状态时。
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.core.env.Environment;
import org.springframework.core.io.Resource;
import org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor;
import org.springframework.jdbc.datasource.init.DataSourceInitializer;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.JpaVendorAdapter;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Optional;
import java.util.Properties;
@Configuration
@EnableTransactionManagement
/* below @CS is not needed with setPackagesToScan */
//@ComponentScan(basePackageClasses = {SomeJpaEntityOne.class, SomeJpaEntityTwo.class})
public class PersistenceJpaConfig {
public static final String SPRING_PROFILE_DEFAULT = "default";
/* the below file-name is purposely not "data.sql" (or data-spring.sql) to avoid/bypass "auto-find" spring-data logic. the file/resource is referred to later in a specific spring profile */
@Value("classpath:developer.local.seed.data.dml.sql")
private Resource seedDataLocalDeveloperResource;
/**
* @param env
* @return
*/
/* bean must be named entityManagerFactory to satisfy spring-jpa magic */
@Bean(name = "entityManagerFactory")
public LocalContainerEntityManagerFactoryBean entityManagerFactory(Environment env) {
final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
em.setDataSource(this.getDataSourceOne());
final String entityManagerFactoryPackagesToScanCsv = "com.myentitiespackageone,com.myentitiespackagetwo";
String[] packagesArray = entityManagerFactoryPackagesToScanCsv.split(",");
em.setPackagesToScan(packagesArray);
final JpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
em.setJpaVendorAdapter(vendorAdapter);
em.setJpaProperties(getCustomHibernateProperties(env, configMapRetriever));
return em;
}
@Bean
public DataSource getDataSourceOne() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("myDataSourceDriverClassName");
dataSourceBuilder.url("mydataSourceUrl");
dataSourceBuilder.username("mydataSourceUserName");
dataSourceBuilder.password("myPassword");
DataSource returnItem = dataSourceBuilder.build();
return returnItem;
}
/**
* @param env
* @param secretRetriever
* @param configMapRetriever
* @return JPA PlatformTransactionManager
*/
/* This bean must be named 'transactionManager' to satisfy jpa string-magic */
@Bean(name = "transactionManager")
public PlatformTransactionManager getAPlatformTransactionManager(Environment env) {
final JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory(env).getObject());
return transactionManager;
}
/**
* @return JPA PersistenceExceptionTranslationPostProcessor
*/
@Bean
public PersistenceExceptionTranslationPostProcessor getAPersistenceExceptionTranslationPostProcessor() {
return new PersistenceExceptionTranslationPostProcessor();
}
final Properties getCustomHibernateProperties(Environment env, IConfigMapRetriever configMapRetriever) {
Properties hibernateProperties = new Properties();
/* not shown */
/* but stuff like
"hibernate.dialect"
"hibernate.hbm2ddl.auto"
"hibernate.jdbc.batch_size"
"hibernate.jdbc.fetch_size"
"hibernate.order_inserts"
"hibernate.order_updates"
"hibernate.jdbc.batch_versioned_data"
"hibernate.generate_statistics"
"hibernate.show_sql"
"hibernate.format_sql"
*/
return hibernateProperties;
}
/**
* @param dataSource
* @return
*/
@Bean
@Profile(SPRING_PROFILE_DEFAULT)
public DataSourceInitializer getDataSourceInitializer(final DataSource dataSource) {
final DataSourceInitializer initializer = new DataSourceInitializer();
initializer.setDataSource(dataSource);
initializer.setDatabasePopulator(getDatabasePopulator());
return initializer;
}
private DatabasePopulator getDatabasePopulator() {
final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
populator.addScript(seedDataLocalDeveloperResource);
return populator;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.