JPA CriteriaQuery Order By Latest Child 属性
JPA CriteriaQuery Order By Latest Child Property
我有 2 个实体:Project 和 ProjectStatus。
项目实体:
@Entity
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@OneToMany(mappedBy = "project")
private List<ProjectStatus> projectStatusses;
}
项目状态实体:
@Entity
public class ProjectStatus {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@ManyToOne
private Project project;
@Enumerated(EnumType.STRING)
private ProjectStatusType statusType;
}
我想通过 CriteriaQuery.orderBy
.
按项目的最新状态类型订购项目
我得出以下结论:
CriteriaQuery<Project> criteriaQuery = criteriaBuilder.createQuery(Project.class);
Root<Project> root = criteriaQuery.from(Project.class);
Join<Project, ProjectStatus> join = root.join("projectStatusses", JoinType.LEFT);
criteriaQuery.orderBy(criteriaBuilder.asc(join.get("statusType")));
我希望上面的查询只考虑最新的项目状态,但我不知道该怎么做。
我怎样才能做到这一点?
更新:
实现这个的sql是:
SELECT proj.*, stat.statustype
FROM project proj
LEFT JOIN projectStatus stat ON proj.id = stat.project_id
WHERE stat.id = (SELECT MAX(id) FROM projectstatus WHERE project_id = proj.id)
ORDER BY stat.statustype
我不喜欢回答我自己的问题,但我找到了解决方案。希望它能对其他人有所帮助。
我的错误是在criteriaQuery.orderBy
方法中寻找解决方案。在 criteriaQuery.where
方法中添加一个子查询就可以了。
解法:
CriteriaQuery<Project> criteriaQuery = criteriaBuilder.createQuery(Project.class);
Root<Project> root = criteriaQuery.from(Project.class);
Join<Project, ProjectStatus> join = root.join("projectStatusses", JoinType.LEFT);
//Create a subquery to get latest ProjectStatus for project
Subquery sq = criteriaBuilder.createQuery().subquery(Long.class);
Root<T> from = sq.from(Project.class);
Path<ProjectStatus> path = root.join("projectStatusses");
//Get latest status
sq.select(criteriaBuilder.max(path.<Long>get("id")));
//For each project
sq.where(criteriaBuilder.equal(from.<Long>get("id"), root.<Long>get("id")));
Predicate latestStatusCondition = criteriaBuilder.and(criteriaBuilder.equal(join.get("id"), sq));
criteriaQuery.orderBy(criteriaBuilder.asc(join.get("statusType")));
criteriaQuery.where(latestStatusCondition);
我有 2 个实体:Project 和 ProjectStatus。
项目实体:
@Entity
public class Project {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@OneToMany(mappedBy = "project")
private List<ProjectStatus> projectStatusses;
}
项目状态实体:
@Entity
public class ProjectStatus {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Long id;
@ManyToOne
private Project project;
@Enumerated(EnumType.STRING)
private ProjectStatusType statusType;
}
我想通过 CriteriaQuery.orderBy
.
我得出以下结论:
CriteriaQuery<Project> criteriaQuery = criteriaBuilder.createQuery(Project.class);
Root<Project> root = criteriaQuery.from(Project.class);
Join<Project, ProjectStatus> join = root.join("projectStatusses", JoinType.LEFT);
criteriaQuery.orderBy(criteriaBuilder.asc(join.get("statusType")));
我希望上面的查询只考虑最新的项目状态,但我不知道该怎么做。 我怎样才能做到这一点?
更新: 实现这个的sql是:
SELECT proj.*, stat.statustype
FROM project proj
LEFT JOIN projectStatus stat ON proj.id = stat.project_id
WHERE stat.id = (SELECT MAX(id) FROM projectstatus WHERE project_id = proj.id)
ORDER BY stat.statustype
我不喜欢回答我自己的问题,但我找到了解决方案。希望它能对其他人有所帮助。
我的错误是在criteriaQuery.orderBy
方法中寻找解决方案。在 criteriaQuery.where
方法中添加一个子查询就可以了。
解法:
CriteriaQuery<Project> criteriaQuery = criteriaBuilder.createQuery(Project.class);
Root<Project> root = criteriaQuery.from(Project.class);
Join<Project, ProjectStatus> join = root.join("projectStatusses", JoinType.LEFT);
//Create a subquery to get latest ProjectStatus for project
Subquery sq = criteriaBuilder.createQuery().subquery(Long.class);
Root<T> from = sq.from(Project.class);
Path<ProjectStatus> path = root.join("projectStatusses");
//Get latest status
sq.select(criteriaBuilder.max(path.<Long>get("id")));
//For each project
sq.where(criteriaBuilder.equal(from.<Long>get("id"), root.<Long>get("id")));
Predicate latestStatusCondition = criteriaBuilder.and(criteriaBuilder.equal(join.get("id"), sq));
criteriaQuery.orderBy(criteriaBuilder.asc(join.get("statusType")));
criteriaQuery.where(latestStatusCondition);