【问题标题】:ORM framework for reactive applications反应式应用程序的 ORM 框架
【发布时间】:2019-06-13 10:46:18
【问题描述】:

我一直在查看 spring-data-r2dbc 以获取响应式数据库访问。但它似乎没有提供任何 ORM 支持,如项目页面所述,它不是 ORM 框架。有哪些选项存在或计划在反应式应用程序中支持 ORM?至于今天为字段指定列名的最佳方法是什么(JPA 中的@Column),使用类层次结构(JPA 中的@MappedSuperclass),最重要的是,在使用 spring-data-r2dbc 时加入?

【问题讨论】:

    标签: spring-data reactive-programming r2dbc spring-data-r2dbc


    【解决方案1】:

    你说得对,spring-data-r2dbc 不是 ORM。它不会映射数据库中的关系。它可以做的是将您的数据库行映射到对象。以下示例 sn-p 被映射到下面的数据库行:

    Kotlin 中的示例类:

    @Table("song")
    class SongRow(
        @Id val id: Long, 
        val name: String, 
        val artist: Long
    )
    

    行:

    create table song(
        id integer identity primary key,
        artist integer references artist(id),
        name varchar(100) NOT NULL,
    );
    

    有关列自动映射到您的模型的方式,请参阅:https://docs.spring.io/spring-data/r2dbc/docs/1.0.0.M1/reference/html/#mapping-usage

    在上面的链接中也说明了,你可以使用@Column。

    至于你的一个问题:

    存在或计划在响应式中支持 ORM 的选项 应用程序? 我不知道

    至于:

    使用 spring-data-r2dbc 时加入

    使用@Query 注解可以执行连接。如果您想实际映射通过连接获得的数据,最好使用 DatabseClient(参见https://docs.spring.io/spring-data/r2dbc/docs/1.0.0.M1/reference/html/#r2dbc.datbaseclient

    【讨论】:

      【解决方案2】:

      Spring Data R2dbc 可以被认为是一个轻量级 ORM 框架。

      映射规则可以在实体类中定义。

      @Data
      @ToString
      @Builder
      @NoArgsConstructor
      @AllArgsConstructor
      @Table(value = "posts")
      public class Post {
      
          @Id
          @Column("id")
          private UUID id;
      
          @Column("title")
          private String title;
      
          @Column("content")
          private String content;
      
          @JsonSerialize(using = PgJsonObjectSerializer.class)
          @JsonDeserialize(using = PgJsonObjectDeserializer.class)
          @Column("metadata")
          private Json metadata;
      
          @Column("status")
          private Status status;
      
          @Column("created_at")
          @CreatedDate
          private LocalDateTime createdAt;
      
          @Column("updated_at")
          @LastModifiedDate
          private LocalDateTime updatedAt;
      
          @Column("version")
          @Version
          private Long version;
      
          enum Status {
              DRAFT, PENDING_MODERATION, PUBLISHED;
          }
      
      }
      

      @Column@Table 来自 spring-data-relational 项目,在 spring-data-r2dbc 和 spring-data-jdbc 之间共享。

      Id 来自 spring-data-commons。

      Spring Data R2dbc 提供R2dbcEntityTemplate(类似于JdbcTemplate)和R2dbcRepository(R2dbc 的特定Repository)。而Spring 5.3,提供了重构的DatabaseClient

      检查 my updated example 以获取 Spring 5.3 中的 R2dbc 和 Spring Data R2dbc。

      但是很遗憾,目前Spring data r2dbc不支持继承和保护。

      如果您坚持使用 JPA/Hibernate,请查看 Hibernate Rx,即 Hibernate 的反应式实现。

      【讨论】:

      • 注意:尽管 Hibernate Rx 很棒,但它仍然存在一些严重的限制,例如不支持多对多关系。
      【解决方案3】:

      可能是lc-spring-data-r2dbc 可以完成这项工作,但你不会发现 JPA 的所有功能。在等待 Hibernate Reactive 发布并集成到 Spring Data 中时,它可能会有所帮助。

      例如,您可以这样声明链接:

      @Table
      public class TableWithForeignKey {
        ...
        @ForeignKey(optional = false)
        private LinkedTable myLink;
        ...
      }
      
      @Table
      public class LinkedTable {
        ...
        @ForeignTable(joinkey = "myLink")
        private List<TableWithForeignKey> links;
        ...
      }
      

      当您希望链接被映射时,您可以使用延迟加载或连接选择。

      如果使用Spring存储库的方法findBy...(findById, findAll...),只会加载存储库的表。在这种情况下,您可以使用延迟加载。为此,您需要声明一个具有默认主体的方法,并且您的方法将自动实现:

        public Flux<TableWithForeignKey> lazyGetLinks() {
          return null; // will be implemented
        }
      

      另一种方法是直接在请求中进行连接。目前不支持在存储库中自动进行连接(如 JPA 中的 @EntitiGraph),但您可以像这样实现您的方法:

      public interface MyRepository extends LcR2dbcRepository<LinkedTable, Long> {
        
        default Flux<LinkedTable> findAllAndJoin() {
          SelectQuery.from(LinkedTable.class, "root") // SELECT FROM LinkedTable AS root
            .join("root", "links", "link")            // JOIN root.links AS link
            .execute(getLcClient());                  // execute the select and map entities
        }
      
      }
      

      结果将是所有 LinkedTable 实例,以及从数据库一起加载的链接列表。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-02-12
        • 1970-01-01
        • 2015-05-13
        • 1970-01-01
        • 1970-01-01
        • 2011-11-28
        • 1970-01-01
        • 2011-04-08
        相关资源
        最近更新 更多