Spring Data JPA 条件实体加入

lev*_*ied 1 java spring jpa spring-data-jpa

我想在 JPA 中映射不寻常的表设置。这是一个简化的示例:

book
  company_id int
  book_id    int
  series_id  int

borrow
  company_id int
  book_id    int
  type       char
Run Code Online (Sandbox Code Playgroud)

问题borrow.book_id是超载:

  • 如果borrow.type是'B',那么borrow.book_id == book.book_id
  • 如果borrow.type是'S',那么borrow.book_id == book.series_id

这种关系在逻辑上borrow是多对一的book。直接用例是:获取borrow给定books列表的所有行。这应该如何在 Spring Data JPA 中映射?

小智 5

您可以在 Book 的 Borrow 实体映射中尝试以下操作 -

@ManyToOne
@JoinColumnsOrFormulas(
    { @JoinColumnOrFormula(
        formula = @JoinFormula(
         value = "case " +
                 "when type == 'B' then book_id" +
                 "when type == 'S' then series_id " +
                 "else 1" +
                 "end", 
         referencedColumnName="book_id")) }
)
Run Code Online (Sandbox Code Playgroud)

但是您需要使用@ManyToOne 注释,即使这似乎是一个@OneToOne 关联。联接公式不适用于 OneToOne。这种方法的缺点是,hibernate 将不必要地创建 2 个连接,这些连接可以使用本机查询仅使用 1 个来完成

如果您使用的是弹簧数据 JPA,那么在您的存储库中,您可以使用以下方法 -

@Query(value="sql stmt with conditional join and IN clause", nativeQuery = true)
List<Idto> findAllBorrowByBook(List<int> bookIds);
Run Code Online (Sandbox Code Playgroud)

其中“Idto”是映射结果集的接口。