我有一个应根据各种参数进行过滤的查询;这些参数之一是一个列表。如果列表中有条目,则应根据条目进行过滤;但如果列表为空/空,则不应对该字段进行任何过滤。
我的想法是这样的:
@Query("select a from Alert a where a.date >= :startDate " +
"and (((:countryIds) is null) or a.countryId in (:countryIds)) " +
"and (((:typeIds) is null) or a.siteTypeId in (:typeIds)) ")
List<Alert> findBy(@Param("startDate") Date startDate,
@Param("countryIds") Set<Long> countryIds,
@Param("typeIds") Set<Long> typeIds);
发送空列表会抛出 NPE;发送一个空列表它会生成以下SQL,这是无效的
where alert0_.date >= '2018-01-01' and
((1, 123) is null or alert0_.countryId in (1, 123))
我也尝试过使用 JPQL,and (((:countryIds) is empty) or a.countryId in (:countryIds))但是在尝试编译 JPQL(在应用程序启动时)时它也不起作用:Caused by: org.hibernate.hql.internal.ast.QuerySyntaxException: ??? is not mapped
at org.hibernate.hql.internal.ast.util.SessionFactoryHelper.requireClassPersister(SessionFactoryHelper.java:171) 或者使用 SpEL: "and (:#{countryIds.size() > 0} or (a.countryId in (:countryIds))) " 但同样,它不会编译 JPQL。
我想到的唯一解决方案是动态生成丑陋的 JPQL 或填充所有现有值countryIds,siteTypeIds这是低效的。
JPA 实现是 Hibernate,数据库是 MySQL。
ibeautiful
相关分类