我正在使用 JPQL 在 JPA 中编写 SQL 查询CurdRepository
界面。我能够使用命名参数编写多个查询,它们的工作方式就像一个魅力。
但是,我的应用程序要求我将未知数量的字符串与表中的多个列进行匹配。据我所知,在 SQL 中它看起来像这样:
SELECT * FROM TABLE WHERE COLUMN_1 LIKE "%string_1%" OR COLUMN_1 LIKE"%string_2%" ... OR COLUMN_2 LIKE "%string_1%" OR COLUMN_2 LIKE "%string_2%" ... ...
我在 MySQL 中尝试过,效果很好。然而,我不知道如何在 JPQL 中描述这一点。我能够传递多个值IN
子句通过将命名参数设置为List
, 如下:
@Query("SELECT t FROM Table t WHERE TABLE_ID IN (:table_ids)")
public Page<Table> findByParameters(@Param("table_ids") List<Integer> table_ids, Pageable page)
我尝试用做同样的事情LIKE
子句,但如果我传递超过 1 个值,我最终会得到 0 个结果。我面临着同样的问题LOCATE
条款也是如此。
最坏的情况是,我可以设置一个适用于一个字符串的查询,并多次调用它,然后合并所有结果。然而,我非常愿意避免这种情况,因为它只不过是一个管道胶带解决方案。
我在网上寻找解决方案几个小时,但没有找到任何可以解决我的问题的内容。任何提示都将受到高度赞赏。
Thanks.
Because @Query
需要在编译时使用 JPQL 进行修复,甚至本机查询都会使此类事情难以实现,尤其是以类型安全的方式实现。
所以我意识到您正在寻找 JPQL 解决方案,但这是一个学习和利用的绝佳机会Specification
接口和 JPA 的 CriteriaQuery。这正是它的用途。
看一下以下存储库:
public interface Table1Repository // to use specifications in queries
extends JpaRepository<Table1, Long>, JpaSpecificationExecutor<Table1> {
@SuppressWarnings("serial")
public static Specification<Table1> multiLikeColumn1(List<String> likePatterns) {
return new Specification<Table1>() {
@Override
public Predicate toPredicate(Root<Table1> root, CriteriaQuery<?> query,
CriteriaBuilder criteriaBuilder) {
Path<String> column1 = root.get("column1");
// create a Predicate for each "column1 like 'xy%az%' you need
List<Predicate> predicates = likePatterns.stream()
.map(likePattern -> criteriaBuilder.like(column1, likePattern))
.collect(Collectors.toList());
// then "concatenate" list of likes with "OR"
return criteriaBuilder.or(predicates.toArray(new Predicate[]{}));
}
};
}
}
它可能看起来有点复杂,但实际上当你熟悉它时并不复杂。用法很简单,例如:
@Resource
private Table1Repository repo;
repo.findAll(Table1Repository.multiLikeColumn1(Arrays.asList("%X%","%Z%")))
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)