在应用程序启动时执行多个脚本
Execute multiple scripts on application startup
我将 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 的说法做了,但是失败并显示一条消息)
There was an unexpected error (type=Internal Server Error, status=500).
org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.h2.jdbc.JdbcSQLException: Schema "~/schema-h2.sql" not found [90079-193]
感谢您的建议
解决方案 1
使用这些附加选项更新您的连接 url:
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'"
This functionality is enabled via the INIT property. Note that
multiple commands may be passed to INIT, but the semicolon delimiter
must be escaped, as in the example below.
你可以这样做:
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;
}
这里是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();
}
我将 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 的说法做了,但是失败并显示一条消息)
There was an unexpected error (type=Internal Server Error, status=500). org.springframework.jdbc.CannotGetJdbcConnectionException: Could not get JDBC Connection; nested exception is org.h2.jdbc.JdbcSQLException: Schema "~/schema-h2.sql" not found [90079-193]
感谢您的建议
解决方案 1
使用这些附加选项更新您的连接 url:
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'"
This functionality is enabled via the INIT property. Note that multiple commands may be passed to INIT, but the semicolon delimiter must be escaped, as in the example below.
你可以这样做:
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;
}
这里是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();
}