避免在Spring Data JPA中的条件构建器查询中重复代码

时间:2018-07-27 13:31:44

标签: spring spring-boot

我正在使用带有Java 1.8的Spring Boot(1.5.14.RELEASE)和Spring数据Jpa。我想避免重复的代码。

以下查询将获取员工详细信息。一切正常。

Class EmployeeDAO:

  CriteriaBuilder cb = em.getCriteriaBuilder();
  CriteriaQuery<EmployeeDto> cq = cb.createQuery(EmployeeDto.class);
  Root<EmployeeInfo> root = cq.from(EmployeeInfo.class);
  Join<EmployeeInfo, SalaryInfo> SalaryType = root.join("SalaryInfo");
  Join<EmployeeInfo, CompanyInfo> Company = root.join("CompanyInfo");

  cq.select(cb.construct(EmployeeDto.class,
      root.get("FirstName"),
      SalaryType.get("Salary"),
      Company.get("CompanyName")))
      .where(specification.toPredicate(root, cq, cb))
      .orderBy(cb.asc(root.get("FirstName")));

同一类中的另一个函数也使几乎90%的标准构建器查询如下所示:

  CriteriaBuilder cb = em.getCriteriaBuilder();
  CriteriaQuery<EmployeeDto> cq = cb.createQuery(EmployeeDto.class);
  Root<EmployeeInfo> root = cq.from(EmployeeInfo.class);
  Join<EmployeeInfo, SalaryInfo> SalaryType = root.join("SalaryInfo");
  Join<EmployeeInfo, CompanyInfo> Company = root.join("CompanyInfo");
  Join<EmployeeInfo, UserInfo> User = root.join("UserInfo");

  cq.select(cb.construct(EmployeeDto.class,
      root.get("FirstName"),
      SalaryType.get("Salary"),
      Company.get("CompanyName"),
      User.get("Age")))
      .where(specification.toPredicate(root, cq, cb))
      .orderBy(cb.asc(root.get("FirstName")));

两个函数中的代码相同,除了下面的代码与UserInfo表进行联接以获取用户年龄。所有其他代码都是重复的。你能告诉我如何避免重复的代码吗?

1 个答案:

答案 0 :(得分:2)

类似这样的东西:

public class EmployeeDAO {

EntityManager em;
Specification specification;

public void get(boolean withUsers) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<EmployeeDto> cq = cb.createQuery(EmployeeDto.class);
    Root<EmployeeInfo> root = cq.from(EmployeeInfo.class);
    Join<EmployeeInfo, SalaryInfo> salaryType = root.join("SalaryInfo");
    Join<EmployeeInfo, CompanyInfo> company = root.join("CompanyInfo");

    List<Selection> sels = new ArrayList<>();
    Collections.addAll(sels,
            root.get("FirstName"),
            salaryType.get("Salary"),
            company.get("CompanyName")
    );
    if (withUsers) {
        Join<EmployeeInfo, UserInfo> user = root.join("UserInfo");
        sels.add(user.get("Age"));
    }

    cq.select(cb.construct(EmployeeDto.class,
            sels.toArray(new Selection[0])
    ))
            .where(specification.toPredicate(root, cq, cb))
            .orderBy(cb.asc(root.get("FirstName")));
}

}