Spring Data JPA - 如何在同一列上实现具有多个值的 LIKE 搜索



假设我有下表,

MOVIE_TITLE

  1. 蝙蝠侠开始
  2. 蝙蝠侠归来
  3. 绝地归来
  4. 指环王:王者归来
  5. 恋爱中的莎士比亚
  6. 死亡诗社
  7. 死侍
  8. 指环王:指环王团契

我想对电影标题进行搜索并传递逗号分隔值(使用多个关键字搜索(

例如

搜索文本: 蝙蝠侠 结果:记录 #1,2

搜索文本: 蝙蝠侠, 返回结果:记录 #1,2,3,4

搜索文本: 主, 爱 结果:记录 #4,5,8

在不循环每个关键字的情况下,是否可以在Spring Data JPA中使用LIKE搜索(或其他内容(在一次调用中实现?

谢谢

我怀疑你有这样的实体

@Entity
public class Movie {
@Id
Long id;
String title;
//getters, setters ...
}

然后你需要存储库扩展JpaSpecificationExecutor

public interface MovieRepository
extends JpaRepository<Movie, Long>, JpaSpecificationExecutor<Movie> {
}

和规范实用程序类

public class MovieSpecification {
public static Specification<Movie> titleContains(String searchWord) {
return (root, query, builder) -> {
Expression<String> titleLowerCase = builder.lower(root.get("title"));
return builder.like(titleLowerCase, "%" + searchWord.toLowerCase() + "%")
}
}
}

服务层上的用法:

MovieRepository repository;
public List<Movie> getMoviesWhereTitleContainsAnyWord(List<String> words) {
if(words.isEmpty()) {
return Collections.emptyList();
}
Specification<Movie> specification = null;   
for(String word : words) {
Specification<Movie> wordSpecification = MovieSpecification.titleContains(word);
if(specification == null) {
specification = wordSpecification;
} else {
specification = specification.or(wordSpecification);
}
}
return repository.findAll(specification);
}

传递给方法的单词越多,由于多个or子句,查询速度就越慢。

如果您真的不想在一个循环中组合多个LIKE,则可以使用正则表达式。但是,T-SQL 中没有标准的正则表达式匹配,但存在依赖于数据库的解决方案。

例如,在 Postgres 中~*您可以使用运算符将列与正则表达式匹配

sql> select 'The Lord of the Rings: The Return of the King' ~* '(King|Queen|Princess|Lord|Duke|Baron)'
[2020-06-03 14:09:28] 1 row retrieved

当然,在查询之前,您必须做一些准备工作。

存储库层:

@Query(value = "select * from Movie_table where movie_title ~* :term", nativeQuery = true)
public List<Object[]> findMovies(@Param("term") String term);

服务层:

String searchText = "Lord, Love";
String searchTerm = Arrays.stream(searchText.split(","))
.map(String::trim)
.filter(StringUtils::isNotBlank)
.collect(Collectors.joining("|", "(", ")"));
List<Object[]> movies = movieRepository.findMovies(searchTerm);
// ... code to convert `Object[]`-s to `Movie` entities ...

附言与多个LIKE/OR查询相比,此解决方案不太优雅

相关内容

  • 没有找到相关文章

最新更新