Hibernate JPA:如何判断参数集合是否为空?
这个问题我之前也碰到过!你踩的坑其实是JPQL里IS EMPTY的用法误解——它只能用来判断实体类里的持久化关联集合(比如User类里标注了@OneToMany的roles集合)是否为空,根本不能直接用来判断你传入的参数集合,这就是为什么启动会报语法错误。
下面给你两种适配Spring Boot 1.5.8.RELEASE的解决方案,根据你查询的复杂度选就行:
方案一:用SpEL表达式在@Query里直接判断(适合中等复杂度查询)
Spring Data JPA支持在@Query里嵌入SpEL表达式,直接判断传入的参数集合是否为空或者null,写法如下:
@Query("SELECT u FROM User u WHERE #{#ids == null or #ids.isEmpty()} OR u.id IN :ids") Collection<User> findUsers(@Param("ids") Collection<String> ids);
这里的#{#ids == null or #ids.isEmpty()}会在查询执行前被解析成布尔值:如果ids是null或者空集合,这个条件为true,会返回所有User;否则就执行id IN :ids的过滤逻辑。
如果你担心SpEL的兼容性,也可以用JPQL的SIZE结合null判断(注意要处理参数为null的情况):
@Query("SELECT u FROM User u WHERE (:ids IS NULL OR SIZE(:ids) = 0) OR u.id IN :ids") Collection<User> findUsers(@Param("ids") Collection<String> ids);
不过这种写法在参数为null时,有些JPA实现可能会对SIZE(:ids)报错,所以更推荐第一种SpEL的写法。
方案二:用Criteria API实现动态查询(适合复杂查询)
既然你说实际查询比较复杂,动态查询会更灵活,不用把所有逻辑硬编码在@Query里。步骤如下:
- 先定义一个自定义Repository接口:
public interface UserRepositoryCustom { Collection<User> findUsers(Collection<String> ids); }
- 实现这个自定义接口:
public class UserRepositoryImpl implements UserRepositoryCustom { @PersistenceContext private EntityManager entityManager; @Override public Collection<User> findUsers(Collection<String> ids) { CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<User> query = cb.createQuery(User.class); Root<User> userRoot = query.from(User.class); // 构建查询条件 Predicate finalPredicate; if (ids == null || ids.isEmpty()) { // 集合为空时,查询所有用户(用恒真条件) finalPredicate = cb.conjunction(); } else { // 集合不为空时,过滤id在集合中的用户 finalPredicate = userRoot.get("id").in(ids); } // 这里可以自由添加其他复杂条件,比如: // finalPredicate = cb.and(finalPredicate, cb.equal(userRoot.get("status"), "ACTIVE")); query.select(userRoot).where(finalPredicate); return entityManager.createQuery(query).getResultList(); } }
- 让你的主Repository接口继承这个自定义接口:
public interface UserRepository extends JpaRepository<User, String>, UserRepositoryCustom { }
之后调用userRepository.findUsers(ids)就能根据参数集合的状态自动切换查询逻辑了,复杂查询的扩展性非常好。
内容的提问来源于stack exchange,提问作者Sasha Shpota
相关产品推荐
相关产品推荐

