繁体   English   中英

动态JPA Spring Boot

[英]Dynamic where JPA Spring Boot

我的Spring Boot应用程序中有一个Table和Pojo,如下所示。

@Entity
@Table(name = "attendance_summary")
public class AttendanceSummary implements Serializable {

  @Id
  @SequenceGenerator(name = "attendance_summary_id_seq",
    sequenceName = "attendance_summary_id_seq",
    allocationSize = 1)
  @GeneratedValue(strategy = GenerationType.SEQUENCE,
    generator = "attendance_summary_id_seq")
  @Column(name = "id", updatable = false)
  public Integer id;

  @Column(name = "emp_id", nullable = false)
  public Integer empId;

  @Column(name = "designation_id")
  public Integer designationId;

  @Column(name = "designation_category_id")
  public Integer designationCategoryId;

  @Column(name = "department_id")
  public Integer departmentId;

  ......
}

现在,我希望这些字段具有动态输入。 意味着用户可以选择empIds,designationIds ...的列表,或它们的任意组合,甚至都不选择。 如果他们没有选择任何字段,则需要返回数据库表中的所有行。

但是在jpa中,当我们在存储库中编写方法时,我们必须指定字段名称,例如

public interface AttendanceSummaryRepository extends JpaRepository<Integer,AttendanceSummary>{
     List<AttendanceSummary> findByEmpIdAndDesignationId....(List<Integer> empIdList,List<Integer> designationIdList ... );
}

这意味着如果这些参数中的任何一个为空,我都会得到一个错误或异常,结果我将丢失一些数据。

在PHP或其他类似语言中,where可以只检查所需过滤器的值,并在查询中动态添加where子句。

query= "Select * from attendance_summary where ";
if(empIdList != null)
    query = query + " emp_id in empIdList "
if(designationIdList != null)
    query = query + " designation_id in designationIdList "
 .....
 //You get the idea. 

有没有办法用jpaDataMethods这样做,如果是的话,怎么做。 任何详细的解释/链接到资源都非常感激。

对不起,英语不好,如果我不能正确解释我的问题。

看一下Criteria API 它允许您创建动态查询。

在您的示例中,类似的方法可能起作用:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<AttendanceSummary> query = cb.createQuery(AttendanceSummary.class);
Root<AttendanceSummary> root = query.from(AttendanceSummary.class);

List<Predicate> predList = new ArrayList<>();
if (empIdList != null) {
    predList.add(root.get('empId').in(empIdList));
}
if (designationIdList != null) {
    predList.add(root.get('designationId').in(designationIdList));
}
// ... You get the idea.

Predicate[] predicates = new Predicate[predList.size()];
predList.toArray(predicates);

query.where(predicates);

return entityManager.createQuery(query).getResultList();

您可以使用@Query批注来实现。 请参阅弹簧指南以获取更多详细信息。

@Query(value = "from attendance_summary where (emp_id in (?1) or ?1 is null) and (designation_id in (?2) or ?2 is null)" )

查询明细:

SELECT * #implicit so removed
FROM   attendance_summary 
WHERE  ( emp_id IN (?1) #true when IDs are not null, thus apply filter
          OR ?1 IS NULL #true when user input null, return all rows ) 
       AND ( designation_id IN (?2) #true when IDs are not null, thus apply filter
              OR ?2 IS NULL #true user input null, return all rows) 

github上的示例项目 ,带有spring-boot,jpa和h2。 查找SchoolControllerSchoolRepo类,应用相同的逻辑,端点\\school将过滤输入Ids的结果,而\\allschool将返回所有内容,因为输入为null。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM