我试图品尝R2dbc并使用嵌入式H2,例如:
public ConnectionFactory connectionFactory() {
//ConnectionFactory factory = ConnectionFactories.get("r2dbc:h2:mem:///test?options=DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE");
return new H2ConnectionFactory(
H2Connectionconfiguration.builder()
//.inmemory("testdb")
.file("./testdb")
.username("user")
.password("password").build()
);
}
然后我定义了一个bean以创建表和初始化数据。
@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")));
populator.addPopulators(new ResourceDatabasePopulator(new ClasspathResource("data.sql")));
initializer.setDatabasePopulator(populator);
return initializer;
}
我还定义了另一个组件,以通过Java代码设置数据。
@Component
@Slf4j
class DataInitializer {
private final Databaseclient databaseclient;
public DataInitializer(Databaseclient databaseclient) {
this.databaseclient = databaseclient;
}
@EventListener(value = ContextRefreshedEvent.class)
public void init() {
log.info("start data initialization ...");
this.databaseclient.insert()
.into("posts")
//.nullValue("id",Integer.class)
.value("title","First post title")
.value("content","Content of my first post")
.map((r,m) -> r.get("id",Integer.class))
.all()
.log()
.thenmany(
this.databaseclient.select()
.from("posts")
.orderBy(Sort.by(desc("id")))
.as(Post.class)
.fetch()
.all()
.log()
)
.subscribe(null,null,() -> log.info("initialization done..."));
}
}
如果我在.inmemory("testdb")
bean定义中使用ConnectionFactory
,则在初始化Spring ApplicationContext
时失败,因为找不到表POSTS
初始化DataInitializer
时。通过启动日志记录,ConnectionFactoryInitializer
已成功初始化,并创建表 POSTS 并通过执行schema.sql和data.sql按预期插入数据。
但是切换为使用.file("./testdb")
确实有效。
完整的代码是here。