Java 基于实体中集合大小的订单结果集
考虑以下实体-Java 基于实体中集合大小的订单结果集,java,spring-boot,spring-mvc,spring-data-jpa,criteriaquery,Java,Spring Boot,Spring Mvc,Spring Data Jpa,Criteriaquery,考虑以下实体- class Team { private String name; @OneToMany private Set<Employee> employees; } class Employee { private String name; @OneToMany private Set<Skill> skills; } class Skill { private String name; p
class Team {
private String name;
@OneToMany
private Set<Employee> employees;
}
class Employee {
private String name;
@OneToMany
private Set<Skill> skills;
}
class Skill {
private String name;
private boolean active;
private Date expiryDate;
}
班级团队{
私有字符串名称;
@独身癖
私人雇员;
}
班级员工{
私有字符串名称;
@独身癖
私人设置技能;
}
课堂技能{
私有字符串名称;
私有布尔活动;
私有日期到期日;
}
我需要对团队结果集进行排序,以使具有最大活动和未过期技能的团队排在第一位。我使用SpringBoot规范和CriteriaQuery来筛选不同领域的团队。到目前为止,我有下面的代码,它不能像预期的那样工作
public class TeamSpecs implements Specification<Team> {
@Override
public Predicate toPredicate(Root<Team> root, CriteriaQuery<?> cq, CriteriaBuilder cb) {
Order o = cb.desc(cb.sum(cb.size(root.join("employees").get("skills")));
cq.orderBy(o));
return cb.like(cb.equal(root.get("name"), "%" + value + "%"));
}
}
public类TeamSpecs实现规范{
@凌驾
公共谓词toPredicate(根根、CriteriaQuery cq、CriteriaBuilder cb){
订单o=cb.desc(cb.sum(cb.size(root.join(“员工”).get(“技能”)));
订购人(o));
返回cb.like(cb.equal(root.get(“name”),“%”+value+“%”);
}
}
我在这里遗漏了什么?请建议要使此功能发挥作用,您首先必须加入表格,然后筛选条目,将其分组,然后对其进行排序 因此,您的SQL查询应该如下所示:
select team.*
from Team team
inner join employee
inner join skill
where skill.active = true and skill.expiryDate > today
group by team.name
order by count(skill.name) desc
旁注:在这种情况下,使用
规范
并不是您想要做的,因为它们并不表示完整的查询,而是在多个查询中使用的语句或查询的一部分
使用JPA标准查询:
public List<Team> getTeamsWithActiveSkills() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Team> cq = cb.createQuery(Team.class);
Root<Team> root = cq.from(Team.class);
Join<Team, Employee> employees = root.join("employees");
Join<Team, Skill> skills = employees.join("skills");
Predicate isActive = cb.isTrue(skills.get("active"));
Predicate isNonExpired = cb.greaterThan(skills.get("expiryDate"), LocalDate.now());
cq.where(isActive, isNonExpired).groupBy(root.get("name"));
Order order = cb.desc(cb.count(skills));
cq.orderBy(order);
return em.createQuery(cq).getResultList();
}
public List<Team> getTeamsWithActiveSkills() {
QTeam team = QTeam.team;
QEmployee employee = QEmployee.employee;
QSkill skill = QSkill.skill;
JPQLQuery<Team> query = from(team).join(team.employees, employee).join(employee.skills, skill);
query = teamJPQLQuery.where(skill.active.isTrue().and(skill.expiryDate.gt(LocalDate.now())));
query = query .groupBy(team.name);
query = query .orderBy(skill.name.count().desc());
return query.fetch();
}
public List getTeamsWithActiveSkills(){
CriteriaBuilder cb=em.getCriteriaBuilder();
CriteriaQuery cq=cb.createQuery(Team.class);
Root=cq.from(Team.class);
加入员工=root.Join(“员工”);
加入技能=员工。加入(“技能”);
谓词isActive=cb.isTrue(skills.get(“active”);
谓词isNonExpired=cb.greaterThan(skills.get(“expireydate”),LocalDate.now();
cq.where(isActive,isNonExpired).groupBy(root.get(“name”));
订单=cb.desc(cb.count(skills));
订购人(订单);
返回em.createQuery(cq.getResultList();
}
因为我个人觉得criteriaquery很难阅读,而且不直观,所以可以将其作为一种替代方法
使用Querydsl:
public List<Team> getTeamsWithActiveSkills() {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<Team> cq = cb.createQuery(Team.class);
Root<Team> root = cq.from(Team.class);
Join<Team, Employee> employees = root.join("employees");
Join<Team, Skill> skills = employees.join("skills");
Predicate isActive = cb.isTrue(skills.get("active"));
Predicate isNonExpired = cb.greaterThan(skills.get("expiryDate"), LocalDate.now());
cq.where(isActive, isNonExpired).groupBy(root.get("name"));
Order order = cb.desc(cb.count(skills));
cq.orderBy(order);
return em.createQuery(cq).getResultList();
}
public List<Team> getTeamsWithActiveSkills() {
QTeam team = QTeam.team;
QEmployee employee = QEmployee.employee;
QSkill skill = QSkill.skill;
JPQLQuery<Team> query = from(team).join(team.employees, employee).join(employee.skills, skill);
query = teamJPQLQuery.where(skill.active.isTrue().and(skill.expiryDate.gt(LocalDate.now())));
query = query .groupBy(team.name);
query = query .orderBy(skill.name.count().desc());
return query.fetch();
}
public List getTeamsWithActiveSkills(){
QTeam team=QTeam.team;
QEmployee employee=QEmployee.employee;
QSkill skill=QSkill.skill;
JPQLQuery query=from(team).join(team.employees,employee).join(employee.skills,skill);
query=teamJPQLQuery.where(skill.active.isTrue()和(skill.expireydate.gt(LocalDate.now());
query=query.groupBy(team.name);
query=query.orderBy(skill.name.count().desc());
返回query.fetch();
}
您面临的问题是什么?获取任何异常?@GovindaSakhare-我在尝试获取特定团队的全部技能时遇到以下错误:java.sql.SQLException:Expression#1 of ORDER by包含聚合函数,并应用于com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)上非聚合查询的结果在com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)在com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)这是否回答了您的问题?你还面临什么问题吗?有更新吗?