Подтвердить что ты не робот

Инициализировать базу данных без конфигурации XML, но используя @Configuration

Я хотел бы знать, как инициализировать базу данных, не создавая файл XML.

Я уже использую такую ​​инициализацию, которая отлично работает, но в моем случае я не хочу создавать XML:

<jdbc:initialize-database data-source="dataSource">
  <jdbc:script location="classpath:com/foo/sql/db-schema.sql"/>
  <jdbc:script location="classpath:com/foo/sql/db-test-data.sql"/>
</jdbc:initialize-database>

Я знаю, что могу создать встроенную базу данных с помощью

EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
EmbeddedDatabase db = builder.setType(H2).addScript("my-schema.sql").addScript("my-test-data.sql").build();

В моем случае база данных и схема создаются с использованием Liquibase.

Я просто хочу инициализировать его с помощью Spring и с моим настроенным набором данных, без необходимости создавать новый XML файл каждый раз только для этого.

Возможно ли это?

4b9b3361

Ответ 1

После просмотра классов Spring, связанных с EmbeddedDatabaseBuilder, я узнал, что DatabaseBuilder использует некоторый код, выглядящий следующим образом:

ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
for (String sqlScript: sqlInitializationScripts ) {
  Resource sqlScriptResource = RESOURCE_LOADER.getResource(sqlScript);
  populator.addScript(sqlScriptResource);
}
DatabasePopulatorUtils.execute(populator, dataSource);

Это сработает для меня, даже если это будет по методу @BeforeTest, а не в конфигурации Spring.

Ответ 2

Следующие строки кода внутри вашего класса @Configuration могут работать.

@Value("classpath:com/foo/sql/db-schema.sql")
private Resource schemaScript;

@Value("classpath:com/foo/sql/db-test-data.sql")
private Resource dataScript;

@Bean
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
    final DataSourceInitializer initializer = new DataSourceInitializer();
    initializer.setDataSource(dataSource);
    initializer.setDatabasePopulator(databasePopulator());
    return initializer;
}

private DatabasePopulator databasePopulator() {
    final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
    populator.addScript(schemaScript);
    populator.addScript(dataScript);
    return populator;
}

Ответ 3

Вам нужно создать свой собственный schema.sql и поместить его в папку src/main/resources.

import javax.sql.DataSource;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.jdbc.datasource.SimpleDriverDataSource;
import org.springframework.jdbc.datasource.init.DatabasePopulator;
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;

@Configuration
public class DataSourceInitializer {

    @Bean(name = "dataSource")
    public DataSource getDataSource(){
        DataSource dataSource = createDataSource();
        DatabasePopulatorUtils.execute(createDatabasePopulator(), dataSource);
        return dataSource;
    }

    private DatabasePopulator createDatabasePopulator() {
        ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator();
        databasePopulator.setContinueOnError(true);
        databasePopulator.addScript(new ClassPathResource("schema.sql"));
        return databasePopulator;
    }

    private SimpleDriverDataSource createDataSource() {
        SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource();
        simpleDriverDataSource.setDriverClass(org.h2.Driver.class);
        simpleDriverDataSource.setUrl("jdbc:h2:target/database/example;AUTO_RECONNECT=TRUE");
        simpleDriverDataSource.setUsername("");
        simpleDriverDataSource.setPassword("");
        return simpleDriverDataSource;      
    }
}

Ответ 4

Это, безусловно, возможно.

Если у вас уже есть класс @Configuration, который загружается Spring ApplicationContext, вам просто нужно создать новый метод @Bean, который будет содержать уже существующий код (с дополнительным return, конечно).

EmbeddedDatabase реализует интерфейс DataSource, поэтому его можно легко использовать с JdbcTemplate.

@Bean
public DataSource db() {
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    builder.setType(H2).addScript("my-schema.sql").addScript("my-test-data.sql");
    return builder.build();
}