【问题标题】:Execute multiple scripts on application startup在应用程序启动时执行多个脚本
【发布时间】:2017-06-11 22:03:25
【问题描述】:

我将 DataSource 定义为 bean:

@Bean(name="dataSource")
public DriverManagerDataSource dataSource() {
    DriverManagerDataSource dataSource = new DriverManagerDataSource();
    dataSource.setDriverClassName("org.h2.Driver");
    dataSource.setUrl("jdbc:h2:~/myDB");
    dataSource.setUsername("sa");
    dataSource.setPassword("");
    return dataSource;
}

它工作得很好,但是我需要指定用于创建数据库的架构并在其上加载数据。有没有机会像 Spring Data 一样执行两个脚本(模式和数据脚本)?我发现的唯一东西是datasource.setSchema(),而且我担心我必须指定它的完整路径。如果我的架构脚本位于src/main/resources/ 路径中,那么如何指定它? (我确实做到了,documentation 怎么说,但它失败并显示一条消息)

出现意外错误(类型=内部服务器错误,状态=500)。 org.springframework.jdbc.CannotGetJdbcConnectionException:无法获得 JDBC 连接;嵌套异常是 org.h2.jdbc.JdbcSQLException: Schema "~/schema-h2.sql" not found [90079-193]

感谢您的建议

【问题讨论】:

  • 你现在如何加载架构?
  • 我无法在 atm 加载它,因为 spring 无法找到它在哪里。正如我之前所说的,datasource.setSchema(String path); 需要完整的 sql 路径。
  • 你用“classpath:schema-h2.sql”试过了吗
  • 看看这个答案:stackoverflow.com/a/27859849/280244,重点:src/main/resources/ 成为类路径,所以文件src/main/resources/test.sql 必须与classpath:test.xml一起加载

标签: java spring jdbc spring-jdbc


【解决方案1】:

这里是Spring official document - Creating an Embedded Database Programmatically

import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;

    @Bean(name = "dataSource")
    public static DataSource H2DataSource() {
        return new EmbeddedDatabaseBuilder()
                .setName("testdb")
                .setType(EmbeddedDatabaseType.H2)
                .addScripts("Your scripts in /resources")
                .build();
    }

【讨论】:

    【解决方案2】:

    解决方案 1

    使用这些附加选项更新您的连接网址:

    DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE;INIT=CREATE SCHEMA IF NOT EXISTS
    

    解决方案 2

    您的 src/main/resources 中应该有一个 application.properties 文件,其中应该包含以下属性:

    spring.datasource.platform=h2
    spring.datasource.initialize=true
    

    解决方法

    您可以将带有脚本位置脚本的 INIT 参数放在您的连接 URL 中(作为选项之一):

    jdbc:h2:mem:test;INIT=RUNSCRIPT FROM '~/schema.sql'\;RUNSCRIPT FROM '~/data.sql'"
    

    此功能通过 INIT 属性启用。注意 可以将多个命令传递给 INIT,但分号分隔符 必须转义,如下例所示。

    【讨论】:

    • 那么,没有机会通过 spring 做到这一点?
    【解决方案3】:

    你可以这样做:

    import org.springframework.jdbc.datasource.init.DatabasePopulator;
    import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils;
    import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
    
    @Bean(name="dataSource")
    public DriverManagerDataSource dataSource() {
       DriverManagerDataSource dataSource = new DriverManagerDataSource();
       dataSource.setDriverClassName("org.h2.Driver");
       dataSource.setUrl("jdbc:h2:~/myDB");
       dataSource.setUsername("sa");
       dataSource.setPassword("");
    
       // schema init
       Resource initSchema = new ClassPathResource("script/schema.sql");
       DatabasePopulator databasePopulator = new ResourceDatabasePopulator(initSchema);
       DatabasePopulatorUtils.execute(databasePopulator, dataSource);
    
       return dataSource;
    }
    

    【讨论】:

    • 我做了一些解决方法,这正是我需要的!我设法运行架构和数据脚本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-16
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-08-15
    相关资源
    最近更新 更多