gpt4 book ai didi

java - Spring JPA - findAll() 带有示例/探针,包括相关/连接的实体

转载 作者:行者123 更新时间:2023-12-02 04:50:32 27 4
gpt4 key购买 nike

如何使用 Spring JPA 的 Query by Example不仅查询实体本身,还使用 ​​findAll() 查询相关实体的属性?当在探针/示例实体上设置相关实体​​属性时,我们所有的尝试似乎都忽略了它们。

文档指出:

The property specifier accepts property names (such as firstname and lastname). You can navigate by chaining properties together with dots (address.city). You can also tune it with matching options and case sensitivity.

但是,没有示例显示链接应该如何工作,并且我们使用它的尝试没有取得成功。

人为示例

假设数据库结构具有多对多关系:

  • 表:书籍

    • id(PK、INT)
    • 标题(varchar)
    • ...
  • 表格:类别

    • id(PK、INT)
    • 姓名
    • ...
  • 表:Book_Category

    • book_id
    • category_id

Book.java

@Data
@Entity
public class Book {
public Book () {}
public Book(String title, List<Category> categories) {
this.title = title;
this.categories = categories;
}

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@NotNull
private String title;

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinTable(
name = "book_category",
joinColumns = {@JoinColumn(name = "book_id")},
inverseJoinColumns = {@JoinColumn(name = "category_id")}
)
private List<Category> categories;
}

BookRepository.java

@Repository
public class BookRepository extends JpaRepository<Book, long> {

}

类别.java

@Data
@Entity
public class Category {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@NotNull
private String name;
}

CategoryRepository.java

@Repository
public class CategoryRepository extends JpaRepository<Category, long> {

}

BookService.java

public class BookService {
@Autowired
private BookRepository bookRepository;

@Autowired
private CategoryRepository categoryRepository;

public List<Book> findByExample(String title, String category) {
ExampleMatcher matcher = ExampleMatcher.matchingAll()
.withMatcher("title", match -> match.contains().ignoreCase())
// ### This is (probably?) the bit that's wrong - none of these made any difference
//.withMatcher("categories.id", match -> match.contains())
//.withMatcher("categories.name", match -> match.contains().ignoreCase())
//.withMatcher("categories", match -> match.contains())
// ###
.withIgnoreNullValues() // ignore unset properties when finding
.withIgnorePaths("id"); // ignore primitives as they default to 0

List<Category> matchingCategories = categoryRepository.findAllByName(category);
Example<Book> example = Example.of(new Book(
title, matchingCategories), matcher);

return bookRepository.findAll(example)
}
}

调用 BookService.findByExample(...) 根据标题正确过滤,但完全忽略类别。 “真实”的例子更复杂,但这提炼出了我们遇到的问题;我们如何过滤相关表和基础表?

最佳答案

这仅适用于 ToOne 关系,不适用于像您的情况那样的 ToMany:

The property specifier accepts property names (such as firstname and lastname). You can navigate by chaining properties together with dots (address.city). You can also tune it with matching options and case sensitivity.

我还查看了 Spring Data 源代码,如下:

for (SingularAttribute attribute : type.getSingularAttributes()) {

因此它只使用 SingularAttribute,如原语、String 和 ToOne 关系。

所以恐怕你想要实现的目标似乎是不可能的。

关于java - Spring JPA - findAll() 带有示例/探针,包括相关/连接的实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56446384/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com