问题描述
@Component
public class TemplateDatabaseLoader {
private Logger LOGGER = LoggerFactory.getLogger(TemplateDatabaseLoader.class);
@Bean
public CommandLineRunner demo(DatabaseClient databaseClient,ItemRepository itemRepository) {
return args -> {
databaseClient.execute(
"CREATE TABLE item (" +
"id SERIAL PRIMARY KEY," +
"name VARCHAR(255)," +
"price REAL" +
");"
).fetch().all().blockLast(Duration.ofSeconds(10));
itemRepository.save(new Item("Alf alarm clock",19.99)).block();
LOGGER.debug("COMMAND LINE RUNNER");
itemRepository.save(new Item("Smurf TV tray",24.99)).block();
};
}
}
并且:
@SpringBootApplication
public class DemoApplication extends AbstractR2dbcConfiguration {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class,args);
}
@Bean
public ConnectionFactory connectionFactory() {
PostgresqlConnectionFactory connectionFactory = new PostgresqlConnectionFactory(PostgresqlConnectionConfiguration.builder()
.host("127.0.0.1")
.database("cart")
.username("cart")
.password("cart").build());
return connectionFactory;
}
@Bean(name={"r2dbcDatabaseClient"})
DatabaseClient databaseClient() {
return DatabaseClient.create(connectionFactory());
}
}
我收到以下错误:
Suppressed: java.lang.Exception: #block terminated with an error
Caused by: io.r2dbc.postgresql.ExceptionFactory$PostgresqlBadGrammarException: relation "item" already exists
Caused by: java.lang.classNotFoundException: org.springframework.jdbc.CannotGetJdbcConnectionException
CREATE TABLE IF NOT EXISTS item
然后,我不再遇到有关项目关系的错误,但是,似乎交易被完全取消了吗?
我得到以下输出:
2020-09-21 17:31:58.476 DEBUG 16639 --- [ restartedMain] com.example.demo.TemplateDatabaseLoader : COMMAND LINE RUNNER
2020-09-21 17:31:58.476 DEBUG 16639 --- [actor-tcp-nio-2] i.r.postgresql.util.FluxdiscardOnCancel : received cancel signal
所以我的问题是
谢谢。
解决方法
我知道了。我添加了一个新类来从文件中加载模式:
@Configuration
public class InitializerConfiguration {
private Logger LOGGER = LoggerFactory.getLogger(InitializerConfiguration.class);
@Bean
public ConnectionFactoryInitializer initializer(ConnectionFactory connectionFactory) {
ConnectionFactoryInitializer initializer = new ConnectionFactoryInitializer();
initializer.setConnectionFactory(connectionFactory);
CompositeDatabasePopulator populator = new CompositeDatabasePopulator();
populator.addPopulators(new ResourceDatabasePopulator(new ClassPathResource("schema.sql")));
initializer.setDatabasePopulator(populator);
return initializer;
}
}
这将在资源下加载schema.sql。我的TemplateDatabaseLoader现在看起来像这样:
@Component
public class TemplateDatabaseLoader {
private Logger LOGGER = LoggerFactory.getLogger(TemplateDatabaseLoader.class);
@Bean
public CommandLineRunner demo(ItemRepository itemRepository) {
return args -> {
itemRepository.save(new Item("Alf alarm clock",19.99)).block();
itemRepository.save(new Item("Smurf TV tray",24.99)).block();
};
}
}
这将加载两个项目。