Spring Boot实现多Genre全匹配查询的方法求助
问题:查询包含所有指定Genre的内容
当前Spring Boot项目中,通过Genre数组查询内容时,返回的是包含任意指定Genre的结果,但实际需求是返回包含所有指定Genre的内容。比如movie1包含drama和comedy,movie2包含crime和drama,当查询条件为comedy和drama时,只应返回movie1,但现有实现会同时返回两者。
现有代码
Repository
@Query(value = "SELECT CONTENTS.ID, CONTENTS.CONTENT_TYPE, CONTENTS.DESCRIPTION, CONTENTS.IMAGE_URL, CONTENTS.TRAILER_URL, CONTENTS.IS_AGE_RESTRICTED, CONTENTS.RELEASE_DATE, CONTENTS.RUNTIME, CONTENTS.SPOKEN_LANGUAGE, CONTENTS.TITLE, CONTENTS.TITLE, GROUP_CONCAT(GENRES.NAME) AS GENRE FROM CONTENTS INNER JOIN GENRES ON CONTENTS.ID=GENRES.CONTENT_ID WHERE GENRE IN (:search) GROUP BY CONTENTS.ID", nativeQuery = true) List<Content> findContentByGenre(String[] search);
Controller
@GetMapping("findAllContentByGenres/genre") public List<Content> getAllContentByGenres(@Param("genre") String[] genre){ return contentService.getAllContentByGenres(genre); }
Service
public List<Content> getAllContentByGenres(String[] genre) { return contentRepository.findContentByGenre(genre); }
解决方案
核心是修改Repository的SQL查询,通过分组后统计匹配的Genre数量,精准筛选出包含所有指定Genre的内容,比你提供的PHP模糊拼接方案更可靠。
修改后的Repository
@Query(value = "SELECT CONTENTS.ID, CONTENTS.CONTENT_TYPE, CONTENTS.DESCRIPTION, CONTENTS.IMAGE_URL, CONTENTS.TRAILER_URL, CONTENTS.IS_AGE_RESTRICTED, CONTENTS.RELEASE_DATE, CONTENTS.RUNTIME, CONTENTS.SPOKEN_LANGUAGE, CONTENTS.TITLE, GROUP_CONCAT(GENRES.NAME) AS GENRE " + "FROM CONTENTS " + "INNER JOIN GENRES ON CONTENTS.ID=GENRES.CONTENT_ID " + "WHERE GENRES.NAME IN (:search) " + "GROUP BY CONTENTS.ID " + "HAVING COUNT(DISTINCT GENRES.NAME) = :searchSize", nativeQuery = true) List<Content> findContentByAllGenres(@Param("search") String[] search, @Param("searchSize") int searchSize);
修改后的Service
public List<Content> getAllContentByGenres(String[] genre) { // 传入查询数组的长度,用于SQL中的计数判断 return contentRepository.findContentByAllGenres(genre, genre.length); }
逻辑说明
- 保留
IN (:search)筛选出包含任意指定Genre的关联记录,但通过GROUP BY CONTENTS.ID将同一内容的所有Genre记录分组 - 新增
HAVING COUNT(DISTINCT GENRES.NAME) = :searchSize:只有当分组内匹配的不同Genre数量和查询条件的数量完全一致时,才返回该内容,确保内容包含所有指定Genre - 为什么不用你提供的PHP拼接逻辑?因为
LIKE '%xxx%'依赖GROUP_CONCAT后的字符串匹配,容易出现误匹配(比如Genre为"dark-comedy"会被"comedy"匹配到),而计数方案更精准。
Controller层无需修改,保持原有代码即可。
内容的提问来源于stack exchange,提问作者Konstantinos Orfeas Kiourtidis
相关产品推荐
相关产品推荐

