java Spring Data JPA通过嵌入对象属性查找

qoefvg9y  于 2023-01-24  发布在  Java
关注(0)|答案(5)|浏览(140)

我想写一个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编写一个查询吗?

lfapxunr

lfapxunr1#

这个方法名应该可以做到:

Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);

更多信息请参见参考文档的查询派生部分。

kmb7vmvb

kmb7vmvb2#

上面的- findByBookIdRegion()对我不起作用,下面的代码适用于最新发布的String Data JPA:

Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);
n3schb8v

n3schb8v3#

如果您使用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;

...
9nvpjoqh

9nvpjoqh4#

据我所知,Spring并不能轻松地处理所有的情况,在您的情况下,下面的方法应该可以解决问题

Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);

Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);

但是,它还取决于@Embeddable类中字段的命名约定,
例如,以下字段可能无法在上述任何样式中工作

private String cRcdDel;

我尝试了这两种情况(如下所示),但都不起作用(似乎Spring不处理这种类型的命名约定(即许多大写字母,特别是开头的第二个字母(不确定是否只有这种情况))

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);
gzjq41n4

gzjq41n45#

有不同的方法来做这件事。
1.使用派生方法。
1.使用本机查询。
1.使用specification interface构建复杂查询。
下面代码段显示如何使用嵌入属性查询数据。
存储库扩展了JpaSpecificationExecutor接口。

public interface QuedBookRepository extends JpaRepository<QueuedBook, Long>, JpaSpecificationExecutor<QueuedBook>{
    //Using derived query methods
    Page<QueuedBook> findByBookId_Region(Region region, Pageable pageable);

    //Using native queries
    @Query("SELECT qb FROM QueuedBook qb "
        +"WHERE qb.bookId.region = :region")
    Page<QueuedBook> findByBookIdRegion(Region region, Pageable pageable);
    
    
    //Using specification interface
    static Specification<QueuedBook> findByBookIdRegion(Region region){
        return (root, query, criteriaBuilder) -> criteriaBuilder.equals(root.get("bookId").get("region"), region);
    }
}

要使用存储库方法,请按如下方式访问它们。

//In your service methods

Region region = ....;
Pageable pageable = ....;

//Using derived query methods
Page<QueuedBook> booksPage = repository.findByBookId_Region(region, pageable);

//Using native queries
Page<QueuedBook> booksPage = repository.findByBookIdRegion(region, pageable);

//Using specification interface
Specification<QueuedBook> spec = QuedBookRepository.findByBookIdRegion(region);
Page<QueuedBook> booksPage = repository.findAll(spec, pageable);

相关问题