我正在使用 R2DBC 和 H2 创建一个快速项目,以使自己熟悉这种新的反应性东西。制作了一个扩展 ReactiveCrudRepository 的存储库,一切都很好,只要我使用 DatabaseClient 发出一个与我的实体匹配的 CREATE TABLE 语句...
我了解 Spring Data R2DBC 的功能不如 Spring Data JPA(还没有?),但目前有没有办法从实体类生成模式?
谢谢
我正在使用 R2DBC 和 H2 创建一个快速项目,以使自己熟悉这种新的反应性东西。制作了一个扩展 ReactiveCrudRepository 的存储库,一切都很好,只要我使用 DatabaseClient 发出一个与我的实体匹配的 CREATE TABLE 语句...
我了解 Spring Data R2DBC 的功能不如 Spring Data JPA(还没有?),但目前有没有办法从实体类生成模式?
谢谢
不,目前无法使用 Spring Data R2DBC 从实体生成模式。
我在一个带有 Postgres DB 的项目中使用它,并且管理数据库迁移很复杂,但我设法在启动时将 Flyway 与同步 Postgre 驱动程序(Flyway 尚不与反应式驱动程序一起使用)连接以处理模式迁移。
即使您仍然需要编写自己的 CREATE TABLE 语句,这不应该那么难,您甚至可以在一些简单的项目中修改您的实体以创建 JPA 实体并让 Hibernate 创建模式,然后将其复制粘贴到您的迁移文件中R2DBC 项目。
可以进行测试和生产。
我生产确保您的用户无权更改架构,否则您可能会错误地删除表!!!或使用像flyway这样的迁移工具。
您需要将您的 schema.sql 放在主要资源中并添加相关属性
spring.r2dbc.initialization-mode=always
h2 用于测试和 postgres 用于生产
我使用 gradle,驱动程序的版本是:
implementation 'org.springframework.boot.experimental:spring-boot-actuator-autoconfigure-r2dbc'
runtimeOnly 'com.h2database:h2'
runtimeOnly 'io.r2dbc:r2dbc-h2'
runtimeOnly 'io.r2dbc:r2dbc-postgresql'
runtimeOnly 'org.postgresql:postgresql'
testImplementation 'org.springframework.boot.experimental:spring-boot-test-autoconfigure-r2dbc'
BOM 版本为
dependencyManagement {
imports {
mavenBom 'org.springframework.boot.experimental:spring-boot-bom-r2dbc:0.1.0.M3'
}
}
这就是我解决这个问题的方法:
控制器:
@PostMapping(MAP + PATH_DDL_PROC_DB) //PATH_DDL_PROC_DB = "/database/{db}/{schema}/{table}"
public Flux<Object> createDbByDb(
@PathVariable("db") String db,
@PathVariable("schema") String schema,
@PathVariable("table") String table) {
return ddlProcService.createDbByDb(db,schema,table);
服务:
public Flux<Object> createDbByDb(String db,String schema,String table) {
return ddl.createDbByDb(db,schema,table);
}
存储库:
@Autowired
PostgresqlConnectionConfiguration.Builder connConfig;
public Flux<Object> createDbByDb(String db,String schema,String table) {
return createDb(db).thenMany(
Mono.from(connFactory(connConfig.database(db)).create())
.flatMapMany(
connection ->
Flux.from(connection
.createBatch()
.add(sqlCreateSchema(db))
.add(sqlCreateTable(db,table))
.add(sqlPopulateTable(db,table))
.execute()
)));
}
private Mono<Void> createDb(String db) {
PostgresqlConnectionFactory
connectionFactory = connFactory(connConfig);
DatabaseClient ddl = DatabaseClient.create(connectionFactory);
return ddl
.execute(sqlCreateDb(db))
.then();
}
连接类:
@Slf4j
@Configuration
@EnableR2dbcRepositories
public class Connection extends AbstractR2dbcConfiguration {
/*
**********************************************
* Spring Data JDBC:
* DDL: does not support JPA.
*
* R2DBC
* DDL:
* -does no support JPA
* -To achieve DDL, uses R2dbc.DataBaseClient
*
* DML:
* -it uses R2dbcREpositories
* -R2dbcRepositories is different than
* R2dbc.DataBaseClient
* ********************************************
*/
@Bean
public PostgresqlConnectionConfiguration.Builder connectionConfig() {
return PostgresqlConnectionConfiguration
.builder()
.host("db-r2dbc")
.port(5432)
.username("root")
.password("root");
}
@Bean
public PostgresqlConnectionFactory connectionFactory() {
return
new PostgresqlConnectionFactory(
connectionConfig().build()
);
}
}
DDL 脚本:
@Getter
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public final class DDLScripts {
public static final String SQL_GET_TASK = "select * from tasks";
public static String sqlCreateDb(String db) {
String sql = "create database %1$s;";
String[] sql1OrderedParams = quotify(new String[]{db});
String finalSql = format(sql,(Object[]) sql1OrderedParams);
return finalSql;
}
public static String sqlCreateSchema(String schema) {
String sql = "create schema if not exists %1$s;";
String[] sql1OrderedParams = quotify(new String[]{schema});
return format(sql,(Object[]) sql1OrderedParams);
}
public static String sqlCreateTable(String schema,String table) {
String sql1 = "create table %1$s.%2$s " +
"(id serial not null constraint tasks_pk primary key, " +
"lastname varchar not null); ";
String[] sql1OrderedParams = quotify(new String[]{schema,table});
String sql1Final = format(sql1,(Object[]) sql1OrderedParams);
String sql2 = "alter table %1$s.%2$s owner to root; ";
String[] sql2OrderedParams = quotify(new String[]{schema,table});
String sql2Final = format(sql2,(Object[]) sql2OrderedParams);
return sql1Final + sql2Final;
}
public static String sqlPopulateTable(String schema,String table) {
String sql = "insert into %1$s.%2$s values (1, 'schema-table-%3$s');";
String[] sql1OrderedParams = quotify(new String[]{schema,table,schema});
return format(sql,(Object[]) sql1OrderedParams);
}
private static String[] quotify(String[] stringArray) {
String[] returnArray = new String[stringArray.length];
for (int i = 0; i < stringArray.length; i++) {
returnArray[i] = "\"" + stringArray[i] + "\"";
}
return returnArray;
}
}