Spring Data JPA 通过嵌入对象属性查找
Posted
技术标签:
【中文标题】Spring Data JPA 通过嵌入对象属性查找【英文标题】:Spring Data JPA find by embedded object property 【发布时间】:2014-08-17 22:46:44 【问题描述】:我想编写一个 Spring Data JPA 存储库接口方法签名,它可以让我在该实体中找到具有嵌入对象属性的实体。有谁知道这是否可行,如果可以,怎么办?
这是我的代码:
@Entity
@Table(name = "BOOK_UPDATE_QUEUE", indexes = uniqueConstraints = @UniqueConstraint(columnNames =
"bookId", "region" , name = "UK01_BOOK_UPDATE_QUEUE"))
public class QueuedBook implements Serializable
@Embedded
@NotNull
private BookId bookId;
...
@Embeddable
public class BookId implements Serializable
@NotNull
@Size(min=1, max=40)
private String bookId;
@NotNull
@Enumerated(EnumType.STRING)
private Region region;
...
public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long>
//I'd like to write a method like this, but can't figure out how to search by region,
//when region is actually a part of the embedded BookId
Page<QueuedBook> findByRegion(Region region, Pageable pageable);
我可以使用 Spring Data 为此编写查询吗?
【问题讨论】:
findByBookIdRegion(Region region, Pageable pageable)
不成功吗?
是的,就是这样。我在任何地方都找不到相关文档。它是隐藏在我没看到的地方还是隐含在某处?
将其转换为答案并添加了指向参考文档相关部分的链接。
【参考方案1】:
在我看来,Spring 并不能轻松处理所有情况。在你的情况下 以下应该可以解决问题
Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);
或
Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);
但是,这也取决于您在 @Embeddable
类中的字段命名约定,
例如以下字段可能不适用于上述任何样式
private String cRcdDel;
我尝试了这两种情况(如下)但它没有工作(似乎 Spring 不处理这种类型的命名约定(即许多 Caps ,尤其是在开头 - 第二个字母(不确定如果这是唯一的情况)
Page<QueuedBook> findByBookIdCRcdDel(String cRcdDel, Pageable pageable);
或
Page<QueuedBook> findByBookIdCRcdDel(String cRcdDel, Pageable pageable);
当我将列重命名为
private String rcdDel;
我的以下解决方案可以正常工作,没有任何问题:
Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
或
Page<QueuedBook> findByBookIdRcdDel(String rcdDel, Pageable pageable);
【讨论】:
【参考方案2】:如果您使用 BookId 作为组合主键,请记住将您的界面更改为:
public interface QueuedBookRepo extends JpaRepository<QueuedBook, Long>
到:
public interface QueuedBookRepo extends JpaRepository<QueuedBook, BookId>
并在你的 QueuedBook 类中将注释 @Embedded 更改为 @EmbeddedId,如下所示:
public class QueuedBook implements Serializable
@EmbeddedId
@NotNull
private BookId bookId;
...
【讨论】:
【参考方案3】:以上 - findByBookIdRegion() 对我不起作用。以下适用于最新版本的 String Data JPA:
Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);
【讨论】:
您的案例可能与 docs.spring.io/spring-data/jpa/docs/current/reference/html/… 讨论的模棱两可有关【参考方案4】:这个方法名应该可以解决问题:
Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);
更多信息请参见参考文档的 query derivation 部分。
【讨论】:
如果我有一个可嵌入列表怎么办?还是元素集合? 如果我们想要 findBy 查询 3 preperty 那么语法是什么?和 findByPro1AndPro2AndPro3 一样吗? 这样的查询总是会导致内连接吗?我正在做One findByIdAndTwoId(Long oneId, Long twoId);
并导致以下形式的查询:select ...... from one one_ left outer join two two_ on one_.two_id = two_.id where one_id = ? and two_.id = ?
@surendrapanday:是的,findByCol1AndCol2
在您有多个列时有效以上是关于Spring Data JPA 通过嵌入对象属性查找的主要内容,如果未能解决你的问题,请参考以下文章
Spring Data JPA:查询如何返回非实体对象或对象列表?
如何禁用嵌入式数据库 Spring-boot spring-data-jpa