java - 如何使用 Hibernate (5.4) Criteria 通过组查询连接两个表?

标签 java jpa join group-by hibernate-criteria

这是我的项目实体:( 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(最新)

(感谢您的阅读以及对开源社区的热爱)

最佳答案

花了无数个小时后,我得到了以下解决方案:

步骤:

  1. 将任务表设为根。
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/

    相关文章:

    SQL 多个 where 子句

    mysql - CakePHP 的多表通用查询模型

    java - JPA @OneToMany 集和独特的内容

    java - Graphics2D 和 JComponent

    java - 如何在不更改 equals 和 hashcode 的情况下插入集合

    java - 为什么在 LWUIT 中按钮有 Action 监听器而命令没有?

    java - 延迟初始化异常 : load lazy attribute from a session different from the original one in Hibernate

    java - 在JavaFx Web View 中打开网页时出错

    java - JPA ManyToMany 持续存在

    mysql - 如何选择第一个表中的所有行并获取其他表中从第一个表检索的每一行的所有匹配行的计数