Java Spring Boot JPA:为同一参数传递多个值(JPQL)
我正在使用JPQL在JPA的CurdRepository接口中编写SQL查询。我能够编写多个带有命名参数的查询,它们工作起来很有魅力 但是,我的应用程序要求我将未知数量的字符串与表中的多个列进行匹配。据我所知,在SQL中,它看起来是这样的:Java Spring Boot JPA:为同一参数传递多个值(JPQL),java,mysql,spring-boot,jpa,jpql,Java,Mysql,Spring Boot,Jpa,Jpql,我正在使用JPQL在JPA的CurdRepository接口中编写SQL查询。我能够编写多个带有命名参数的查询,它们工作起来很有魅力 但是,我的应用程序要求我将未知数量的字符串与表中的多个列进行匹配。据我所知,在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 L
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子句传递多个值,如下所示:
@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子句也面临同样的问题
最坏的情况是,我可以在一个字符串上设置一个查询,并多次调用它,然后合并所有结果。不过,我更愿意避免这种情况,因为它只不过是一种管道胶带解决方案
我在网上找了几个小时的解决方案,但没有找到任何解决我的问题的方法。任何提示都非常感谢
谢谢。因为@Query需要在编译时使用JPQL或甚至本机查询进行修复,这将使此类事情很难实现,尤其是以类型安全的方式实现
所以我知道你们在追求JPQL解决方案,但这是一个极好的机会来学习和利用规范接口和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[]{}));
}
};
}
}
您可以访问spring存储库使用的EntityManager吗?我的意思是,你有一个可以注入EntityManager的服务吗?@CarlitosWay我有一个服务,但我没有使用EntityManager。我有一个实现crudepository的存储库接口,并使用该服务调用来自所述存储库的不同方法。更好的是,可以执行以下操作以返回分页结果:repo.findAllTable1Repository.multilikecolumn1array.asList%X%,%Z%,new PageRequestpagenum,page\u offset
@Resource
private Table1Repository repo;
repo.findAll(Table1Repository.multiLikeColumn1(Arrays.asList("%X%","%Z%")))