这是我的项目实体:( Project.java )
@Entity
@Table(name = "project")
public class Project implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column
private String name;
@Column
private String description;
@OneToMany(
mappedBy = "project",
cascade = CascadeType.REMOVE,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private List<Task> tasks = new ArrayList<>();
public Project() {}
public Project(String name, String description) {
this.name = name;
this.description = description;
}
// getter setter here
}
这是我的任务实体:( Task.java )
@Entity
@Table(name = "task")
public class Task implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@Column(name = "title")
private String title;
@Column(name = "description")
private String description;
@ManyToOne
@JoinColumn(name = "project_id", referencedColumnName="id")
private Project project;
public Task() {}
public Task(String title, String description) {
this.title = title;
this.description = description;
}
// getter setter here
}
所需的 DTO:( ProjectWithSumOfTaskDto.java )
public class ProjectWithSumOfTaskDto {
private int projectId;
private String name;
private long totalTasks;
public ProjectWithSumOfTaskDto(int id, String name, long totalTasks) {
this.projectId = id;
this.name = name;
this.totalTasks = totalTasks;
}
// getter setter here
}
数据库中的表结构:
任务:
- ID
- 标题
- 描述
- project_id
项目:
- ID
- 姓名
- 描述
主要问题:
我现在需要的是按“project_id”列加入“项目”表和“任务”表分组。并获取 List 作为输出。
我已经用 HQL 完成了它,现在我必须学习如何在 hibernate 标准中完成它。
我正在使用 hibernate 版本 5.4(最新)
(感谢您的阅读以及对开源社区的热爱)
最佳答案
花了无数个小时后,我得到了以下解决方案:
步骤:
- 将任务表设为根。
Root<Task> task = criteria.from(Task.class);
- 用Task加入Project,并将JoinType设置为Left join。
Join<Task, Project> projectJoin = task.join(Task_.project, JoinType.LEFT);
- 按“tasks”表的“project_id”分组。
criteria.groupBy(task.get(Task_.project));
- 使用多选并选择task.project_id、project.name以及group by后的任务行数。
criteria.multiselect(projectJoin.get(Project_.ID).alias("projectId"),
projectJoin.get(Project_.NAME).alias("name"),
builder.count(task).alias("totalTasks"));
- 最后返回了我想要的 DTO 列表,如下所示:
return session.createQuery(criteria).getResultList();
总的来说,代码将如下所示:
public List<ProjectWithSumOfTaskDto> projectsWithTaskCount() {
return criteriaBuilderContext((session, builder) -> {
CriteriaQuery<ProjectWithSumOfTaskDto> criteria = builder.createQuery(
ProjectWithSumOfTaskDto.class
);
Root<Task> task = criteria.from(Task.class);
Join<Task, Project> projectJoin = task.join(Task_.project, JoinType.LEFT);
criteria.groupBy(task.get(Task_.project));
criteria.multiselect(
projectJoin.get(Project_.ID).alias("projectId"),
projectJoin.get(Project_.NAME).alias("name"),
builder.count(task).alias("totalTasks")
);
return session.createQuery(criteria).getResultList();
});
}
关于java - 如何使用 Hibernate (5.4) Criteria 通过组查询连接两个表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64216085/