呼~,總算搞出來了這個功能,開始覺得搞不出來只是由於對jpa的各類接口不熟悉,但在這周換了方案搞時才發現事情沒那麼簡單——本身對sql瞭解的也很膚淺!mysql
試題和標籤多對多,能夠選擇多個標籤來查找擁有這些標籤的試題,開始的想法是找出須要查詢的標籤,而後找出試題的標籤,前者所有在後者中便是要查詢的結果,理想很豐滿:sql
Subquery returns more than 1 row
mysql 並不支持本身這樣操做。ui
上面的路行不通,本身又想不到其餘思路(還有曲線救國,先查詢再過濾,先不論效率,這是分頁查詢,因此就不能用這個方法),只能問潘老師,潘老師給出瞭解決辦法:debug
查詢時嘗試使用count
結合in
的方式,本身寫HSQL語句
如果沒接觸過,對於這句話多是懵的,由於本身開始就是,count
用於計算查詢出來的數據條數,他和in
有什麼聯繫?code
讓咱們看看解決這個問題的sql(tag爲標籤,subject爲試題)接口
select subject0_.id from subject subject0_ #將表進行鏈接 inner join subject_tags tags1_ on subject0_.id=tags1_.subjects_id inner join tag tag2_ on tags1_.tags_id=tag2_.id where tag2_.id in ( # 查詢的tagId 4,5 ) group by subject0_.id having # 這裏須要等於查詢的tagId的數量 count(subject0_.id)=2
關鍵就在於:查詢的tagId有幾個就須要查詢出幾條結果,由於須要每一個查詢條件都知足才能符合查詢要求。ci
sql語句對應的Hibernate的查詢寫法:get
public Page<Subject> pageAllByCurrentUser(Pageable pageable, Long courseId, Long modelId, Integer difficult, List<Long> tagIds) { return subjectRepository.findAll((Specification<Subject>) (root, query, builder) -> { …… if (tagIds != null && tagIds.size() > 0) { ListJoin<Subject, Tag> subjectTagListJoin = root.joinList("tags", JoinType.INNER); predicate = subjectTagListJoin.get("id").in(tagIds); logger.debug("進行分組"); query.groupBy(root.get("id")); logger.debug("每一個條件都會查出一條相應的數據"); query.having(builder.equal(builder.count(root.get("id")), tagIds.size())); } return predicate; }, pageable); }