簡體   English   中英

如何使用 Hibernate (5.4) Criteria 通過組查詢連接兩個表?

[英]How to join two tables with a group query using Hibernate (5.4) 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
  • 標題
  • 描述
  • 項目編號

項目:

  • ID
  • 姓名
  • 描述

主要問題:

我現在需要的是加入按“project_id”列分組的“projects”表和“tasks”表。 並獲得 List 作為輸出。

我已經用 HQL 做到了,現在我必須學習如何在休眠標准中做到這一點。

我正在使用休眠版本 5.4(最新)

(感謝閱讀和對開源社區的熱愛)

我沒有使用你的 dto 我使用的是你的基類,我也不運行它,解決方案是:

Criteria cr = session.createCriteria(Project.class, "p");
cr.createAlias("p.tasks", "t", Criteria.INNER_JOIN);
cr.add(Restrictions.eq("p.id",id);
return cr.list();

我希望這是有幫助的

花了無數個小時后,我找到了以下解決方案:

腳步:

  1. 將任務表設為 Root。
Root<Task> task = criteria.from(Task.class);
  1. 將 Project 與 Task 合並,並將 JoinType 設為 Left join。
Join<Task, Project> projectJoin = task.join(Task_.project, JoinType.LEFT);
  1. 按“tasks”表的“project_id”分組。
criteria.groupBy(task.get(Task_.project));
  1. 使用多選並選擇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"));
  1. 最后像這樣返回了我想要的 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();
    });
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM