【发布时间】:2021-10-04 16:46:55
【问题描述】:
我有两个具有多对多关系的实体:
@Entity
@Table(name = "author")
public class Author {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "author_name", unique = true)
private String authorName;
@ManyToMany // default FetchType.LAZY
@JoinTable(name = "author_book",
joinColumns = @JoinColumn(name = "author_id"),
inverseJoinColumns = @JoinColumn(name = "book_id"))
private Set<Book> books;
// other fields, getters, setters
}
和
@Entity
@Table(name = "book")
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
@Column(name = "title", unique = true)
private String title;
// other fields, getters, setters
}
假设我们在数据库中有 1 位作者,作者名称为“Stephen King”,相关的 3 本书的标题为“book-title-1”,“book-title-2', 'book-title-3'.
我需要通过作者的姓名获取具有特定标题的书籍,例如:
查找名为“Stephen King”的作者,其书籍名为“book-title-1”或“book-title-2”
通过下面的查询,它可以工作,即我得到了一个具有一组 两个 书籍元素的作者。
public interface AuthorRepository extends JpaRepository<Author, Long> {
@Query("select a from Author a join fetch a.books b " +
"where a.authorName=:authorName and b.title in :titles")
Optional<Author> findByNameAndBookTitles(String authorName, Set<String> titles);
}
上述方法的休眠查询(简化):
select author.id, book.id, author.author_name, book.title, author_book.author_id, author_book.book_id
from public.author
inner join public.author_book on author.id= author_book.author_id
inner join public.book on author_book.book_id=book.id
where author.author_name=? and (book.title in (? , ?))
问题:有没有办法通过查询方法名称来重写它?
我是这样尝试的:
Optional<Author> findByAuthorNameAndBooks_titleIn(String authorName, Set<String> titles);
但它返回作者和所有相关的书籍而不是两本书,所以hibernate会进行以下两次查询(第二次hibernate查询是在第一次访问Set<Book> books时进行的):
Hibernate:
select author.id , author.author_name
from public.author
left outer join public.author_book on author.id = author_book.author_id
left outer join public.book on author_book.book_id= book.id
where author_name=? and (book.title in (? , ?))
Hibernate:
select author_book.author_id, author_book.book_id, book.id, book.title
from public.author_book
inner join public.book on author_book.book_id=book.id
where author_book.author_id=?
我建议它可能与 @ManyToMany(fetch = FetchType.EAGER) 一起使用,但 hibernate 再次像上面一样进行了两次查询,唯一的区别是第二次查询是在第一次调用账套之前进行的。
如果您需要任何澄清,请提前告诉我并感谢您。
【问题讨论】:
-
不应该是findByNameAndTitleIn(String name, Set
titles)吗? -
@MrFisherman 标题是
Book类的属性,而不是Author的属性 -
对,对不起:)。
-
tou 也可以试试“title”这个词的首字母大写吗?比如 findByAuthorNameAndBooks_TitleIn。互联网上所有类似的查询都以大写字母开头,例如stackoverflow-com.translate.goog/a/… 或docs-spring-io.translate.goog/spring-data/jpa/docs/current/…
-
@MrFisherman 谢谢,试过了,但行为没有改变,它还获取所有相关书籍
标签: java spring spring-boot hibernate jpa