【问题标题】:Can spring data r2dbc generate a schema?spring data r2dbc 可以生成模式吗?
【发布时间】:2020-02-29 05:18:11
【问题描述】:

我正在使用 R2DBC 和 H2 创建一个快速项目,以熟悉这种新的反应式东西。制作了一个扩展 ReactiveCrudRepository 的存储库,一切都很好,只要我使用 DatabaseClient 首先发出与我的实体匹配的 CREATE TABLE 语句...

我了解 Spring Data R2DBC 的功能不如 Spring Data JPA(还没有?),但目前有办法从实体类生成架构吗?

谢谢

【问题讨论】:

    标签: java schema spring-data-r2dbc


    【解决方案1】:

    不,目前无法使用 Spring Data R2DBC 从实体生成架构。

    我在一个带有 Postgres DB 的项目中使用它,并且管理数据库迁移很复杂,但我设法在启动时将 Flyway 与同步 Postgre 驱动程序(Flyway 不支持反应式驱动程序)连接起来以处理模式迁移.

    即使您仍然需要编写自己的 CREATE TABLE 语句,这不应该那么难,您甚至可以在一些简单的项目中修改您的实体以创建 JPA 实体并让 Hibernate 创建模式,然后将其复制粘贴到迁移中R2DBC 项目中的文件。

    【讨论】:

      【解决方案2】:

      可以用于测试和生产。

      我确保您的用户无权更改架构,否则您可能会误删除表!!!或使用 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'
          }
      }
      

      【讨论】:

        【解决方案3】:

        我就是这样解决这个问题的:

        控制器:

            @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;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2019-10-14
          • 2020-11-29
          • 1970-01-01
          • 2021-01-30
          • 2020-07-04
          • 2020-09-22
          • 1970-01-01
          • 2022-11-07
          相关资源
          最近更新 更多