java - 使用 Criteria API 的复杂请求
问题描述
我正在实施某种学校逻辑。我有学生实体女巫有他通过的考试清单:
@Entity
@Getter
@Setter
public class Student {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "student_id")
private Long id;
@Column("name")
private String name;
@OneToMany(mappedBy = "student", cascade = CascadeType.ALL)
private List<Exam> exams;
}
考试本身具有标记值和 prePost 标识符(考试可以在上课之前或之后)
@Entity
@Getter
@Setter
public class Exam {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "exam_id")
private Long id;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "student_id")
private Student student;
@Column("prePost")
private String prePost;
@Column("mark")
private int mark;
}
应该实施的要点之一是按姓名和他们通过的考试搜索学生。在前端有三个过滤器:学生姓名和考试标记。好吧,我正在为这个逻辑使用 Criteria API。这里的主要思想是创建一组规范,然后调用 StudentRepository 方法:
List<Student> findAll(Specification<Student> spec);
其中 spec 是所有创建的 Specification 对象的结合结果。
好吧,我在通过考试实施搜索时遇到了困难。让我借助元语言中的 if-else 语句来解释正确的逻辑。
if(student has at least one Post Exam) {
for(Exam exam : student.exams) {
if(exam.mark == selectedMark && exam.prePost == POST){
*Current student is suitable*
}
}
} else {
for(Exam exam : student.exams) {
if(exam.mark == selectedMark && exam.prePost == PRE){
*Current student is suitable*
}
}
}
这是在女巫的帮助下我尝试实现此逻辑的代码
private Specification<Student> participantByExam(final Integer mark) {
return Objects.nonNull(mark) ? (root, query, cb) -> {
final Subquery<Exam> subquery = query.subquery(Exam.class);
final Root<Exam> examRoot = subquery.from(Exam.class);
final Expression<Object> expression = cb.selectCase()
.when(cb.equal(root.join(Student_.exams).get(Exam.prePost), POST), cb.literal(POST))
.otherwise(cb.literal(PRE));
final Predicate predicate = cb.and(
cb.equal(examRoot.get(Exam_.student), root),
cb.equal(examRoot.get(Exam_.mark), mark),
cb.equal(examRoot.get(Exam_.prePost), expression)
);
query.distinct(true);
subquery
.select(root.join(Student_.exams))
.where(predicate);
return cb.exists(subquery);
} : null;
}
我在这里遇到的问题是不正确地使用连词:与有后期测试的学生和对他们的一个结果有一定分数的学生有连词。但我想接收具有一定分数的后考试的学生。
你能以某种方式帮助我这样复杂的请求逻辑吗?或者也许为此编写正确的 SQL 请求。
解决方案
推荐阅读
- ios - 如何在 Swift 5.1 中创建圆形计算器按钮?
- node.js - 如何从快速节点js中的查询中获取键和值
- c# - How to constantly update stamina system
- authentication - 限制可以登录网站的用户设备的最佳方法是什么
- amazon-web-services - 如何生成可访问的文件 url 到 s3 存储桶?
- c++ - CMake将Qt运行时库复制到可执行输出路径
- apache-kafka - io.smallrye.config.ConfigValidationException:配置验证失败
- php - 程序功能发生的相反结果
- c++ - GLFW - 如何将变量输入消息框中,以免它们显示中文
- aws-sdk - 在执行 restoreDBInstanceFromDBSnapshot AWS SDK 调用时指定用户和密码