在JPA中处理空或null集合参数

r7s23pms  于 2022-11-24  发布在  其他
关注(0)|答案(2)|浏览(544)

org.springframework.data.jpa.repository.@Query注解中,我检查字段是否在集合中,如果它为空,则可能忽略集合:

@Query(""select e from #{#entityName} where e.type in :lst or 0 = :lstSize")
List<Entity> findByLst(@Param("lst") List<XEnum> lst, @Param("lstSize") int lstSize);

我的调用代码为:

List<XEnum> lst = ...;
int lstSize = (lst == null) ? 0 : lst.size();
findByLst(lst, lstSize);

对于Oracle数据库,如果记录lst = null休眠:

DEBUG [nio-8443-exec-4] org.hibernate.SQL
entity0_.type in (?) or 0=?
TRACE [nio-8443-exec-4] org.hibernate.type.EnumType
Binding null to parameter: [1]
TRACE [nio-8443-exec-4] org.hibernate.type.descriptor.sql.BasicBinder
binding parameter [2] as [INTEGER] - [0]

对于记录的lst = new LinkedList<>()休眠情况:

DEBUG [nio-8443-exec-5] org.hibernate.SQL
entity0_.type in ( ) or 0=?
TRACE [nio-8443-exec-5] org.hibernate.type.descriptor.sql.BasicBinder
binding parameter [1] as [INTEGER] - [0]
ERROR [nio-8443-exec-5] org.hibernate.engine.jdbc.spi.SqlExceptionHelper
ORA-00936: missing expression

而且它在SQL*PLUS中语法上也是无效:

select 1 from dual where 1 in ();

我是否可以省略lstSize并仍然检查是否未提供集合-返回所有元素?
如何处理空列表和Oracle ()语法错误?
实际上,我有一个很大的JPQL表达式,可以用一个调用来处理几个空参数的情况。我的目标是保持简单的方法,而不是写几个专门的方法,使用if/else或Critetia builder...
例如,忽略空参数可使用以下命令存档:

... and (e.field = :fieldVal or :fieldVal is null)

更新相关资源:

ssm49v7z

ssm49v7z1#

Criteria API代表救援。
您正在动态地构建SQL查询(当您通过构建工具插件从实体生成特殊类时,有可能实现 * 类型安全 *)。
Spring Data以org.springframework.data.jpa.domain.Specification + org.springframework.data.jpa.repository.JpaSpecificationExecutor的形式提供了方便,因此查询可能类似于:

Specification<Book> spec = (Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder builder) -> {
    ...
    if (CollectinUtils.isNotEmpty(ids)) {
        root.get("id").in(ids);
    }
}
List<Book> booksByIds = repository.findAll(spec);

Hibernate条件API支持ANDOR中的null,忽略该表达式,以便在将IN运算符生成器放入实用函数时省略空检查。

2vuwiymt

2vuwiymt2#

您可以使用JPA非空或IsNotEmpty
示例代码
实体名称

public class products{
  ....fields

  @OneToMany(mappedBy = "productId")
  @JsonIgnore
  private List<Rating> ratingList;

  .....geter/setter
}

public class Rating{
  ....fields
 
 @JoinColumn(name = "product_id", referencedColumnName = "id")
 @ManyToOne
 @JsonIgnore
 private Products productId;

  .....geter/setter

}

资料档案库

public interface ProductRepository extends JpaRepository<Products, Integer>{
   public Page<Products> findByRatingListNotEmpty(Pageable pg);
}

相关问题