spring - Avoid duplicate code in criteria builder query in spring data jpa
问题描述
I am using Spring Boot (1.5.14.RELEASE) and Spring data Jpa with Java 1.8. I want to avoid duplicate code.
Below query fetches employee details. It's working fine.
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")));
Another function in same class in also making the almost 90% same criteria builder query as shown below:
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")));
The code in both function is same except that below code is making join with UserInfo table to get user age. All other code is duplicate. Can you tell me how can I avoid this duplicate code.
解决方案
像这样的东西:
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")));
}
}
推荐阅读
- python - 如何访问 pytest.parametrize 中的测试索引
- amazon-web-services - ec2 用户数据脚本仅部分执行
- c++ - 使用 SDL2 和 SDL_image 加载 C++ 图像
- scala - 带有当前行条件的 Spark 窗口函数
- c# - 禁用控件上的所有鼠标消息
- mysql - 如何创建 perl 脚本以访问许多主机并更新或执行自定义作业
- javascript - JSON.stringify() - 对象的自定义序列化器
- azure - 获取 PnPUnifiedGroup:代码:Authorization_RequestDenied
- r - 我在 R 中导入了一个通过调查创建的数据集,其中只有数值。但是,一旦我将它加载到 R 中,只会出现 NA
- python - 使用循环检查字符串的标点符号