【问题标题】:Avoid duplicate code in criteria builder query in spring data jpa避免在spring data jpa中的标准构建器查询中重复代码
【发布时间】:2023-03-12 04:16:02
【问题描述】:

我在 Java 1.8 中使用 Spring Boot (1.5.14.RELEASE) 和 Spring data 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 表进行连接以获取用户年龄。所有其他代码都是重复的。你能告诉我如何避免这个重复的代码。

【问题讨论】:

  • 我想做的是制作一个应该包含通用代码的通用函数。上面两个代码块都应该调用这个函数来获取公共代码,然后在需要时添加进一步的连接。
  • 为什么不使用spring-data-jpa 存储库或querydsl 来生成谓词?

标签: spring spring-boot


【解决方案1】:

类似这样的:

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")));
}

}

【讨论】:

    猜你喜欢
    • 2021-05-17
    • 2019-02-05
    • 2016-04-04
    • 2016-02-29
    • 2016-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-11-05
    • 1970-01-01
    相关资源
    最近更新 更多