在没有XML配置的情况下初始化数据库,但使用@Configuration

Seb*_*ber 43 java spring h2

我想知道如何在不创建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>
Run Code Online (Sandbox Code Playgroud)

我知道我可以创建一个嵌入式数据库:

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

在我的例子中,数据库和模式是使用Liquibase创建的.

我只想用Spring和我的自定义数据集初始化它,而不必每次都为此创建一个新的XML文件.

可能吗?

小智 35

您的@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;
}
Run Code Online (Sandbox Code Playgroud)


Jan*_*sen 25

你必须创建自己的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;      
    }
}
Run Code Online (Sandbox Code Playgroud)

  • @SebastienLorber我对Value注释有一些问题,所以我不得不重写它.以上是我的结果,它的工作原理:) (2认同)

nic*_*ild 6

这当然是可能的.

如果你已经有一个@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();
}
Run Code Online (Sandbox Code Playgroud)


Seb*_*ber 6

在查看与EmbeddedDatabaseBuilder相关的Spring类之后,我发现DatabaseBuilder使用的代码如下所示:

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

这对我来说很好,即使它将在@BeforeTest方法而不是Spring配置上.