【问题标题】:Hibernate : self join confusion?Hibernate:自我加入混乱?
【发布时间】:2015-10-18 13:11:10
【问题描述】:

我有一个category 表。其中前 5 个是主要类别,并且 其他是子类别。

我需要获取前 5 个主要类别的子类别,所以我找到了 sql 查询

SELECT m.category_id,m.category_name  AS 'Parent',
      e.category_name AS 'Sub'
FROM category e
INNER JOIN category m ON m.category_id = e.parent_category_id
ORDER BY Parent

查询正在加入同一个表本身。并得到下面给出的结果

结果

如何将 SQL 查询转换为 HQL 并将如上图所示的数据返回给用户 标准的json格式?

FetchSubCategory

import java.io.Serializable;
import java.util.Set;
import javax.persistence.*;

@Entity
@Table(name = "category")
public class FetchSubCategory implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "category_id")
    private Integer categoryId;

    @Column(name = "category_name")
    private String categoryName;

    @ManyToOne(cascade = {CascadeType.ALL})
    @JoinColumn(name = "parent_category_id")
    private FetchSubCategory parent;

    @OneToMany(mappedBy = "parent")
    private Set<FetchSubCategory> subCategory;

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public FetchSubCategory getParent() {
        return parent;
    }

    public void setParent(FetchSubCategory parent) {
        this.parent = parent;
    }

    public Set<FetchSubCategory> getSubCategory() {
        return subCategory;
    }

    public void setSubCategory(Set<FetchSubCategory> subCategory) {
        this.subCategory = subCategory;
    }

}

方法

public Set<FetchSubCategory> fetchSubCategory() throws SQLException, ClassNotFoundException, IOException {
        Set<FetchSubCategory> groupList = null;
        try {
            Session session = sessionFactory.getCurrentSession();
            Query query = session.createQuery("SELECT m.categoryName AS 'Parent', e.categoryName AS 'Sub' FROM FetchSubCategory e INNER JOIN FetchSubCategory m ORDER BY Parent");

            groupList = (Set<FetchSubCategory>) query.list();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return groupList;
    }

谁能纠正我的错误并告诉我如何获取如上图所示的结果?

【问题讨论】:

  • 你试过什么?您是否阅读过有关 HQL 和连接的文档? docs.jboss.org/hibernate/orm/4.3/manual/en-US/html/ch16.html
  • 请帮我这样做,这样我就可以理解基本步骤,然后按照相同的步骤操作。 @JB 尼泽特
  • StackOverflow 不是一个“请做好我的工作,因为我懒得阅读文档并自己尝试一些东西”的网站。尽你的本分。你可能会……在这个过程中学到一些有用的东西。
  • 这不是因为懒惰,我不知道在 Hibernate 中像这些东西一样使用 AS 'Parent' 和 AS 'Sub'。这就是为什么在这里提出我的疑问..我也已经阅读了这些文档。 .
  • 您有@OneToMany(mappedBy = "category"),但在FetchSubCategory 类中没有category 属性。你的意思可能是@OneToMany(mappedBy = "manager")。按照您构建类的方式,FetchSubCategory 的每个实例都包含对其父类别 (manager) 的引用(如果存在)。因此,您甚至不需要执行连接查询。如果您只是解雇from FetchSubCategory where manager is not null order by manager.categoryName,您将获得分配了经理的所有类别。然后,您可以简单地迭代结果,就是这样。

标签: java mysql spring hibernate rest


【解决方案1】:

对于您的情况下的自我加入,以下内容适合您。

    @ManyToOne(cascade={CascadeType.ALL})    
    @JoinColumn(name = "parent_category_id")
    private FetchSubCategory parent;

    @OneToMany(mappedBy = "parent")
    private Set<FetchSubCategory> subCategory;

FetchSubCategory 实体类,我们定义了两个属性:FetchSubCategory parent and Set&lt;FetchSubCategory&gt; subCategory。属性 parent 用@ManyToOne 注解映射,从属属性用@OneToMany 映射。同样在@OneToMany 属性中,我们将mappedBy="parent" 定义为relationship owner,从而管理表中的外部关系。

注释@JoinColumn 也定义在parent 上,使其成为关系所有者。 @JoinColumn 定义了连接列,在我们的例子中是parent_category_id

【讨论】:

  • 请告诉我查询结果如何?
【解决方案2】:

这些东西会解决你的问题

@Entity
@Table(name = "category")
public class FetchSubCategory implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "category_id")
    private Integer categoryId;

    @Column(name = "category_name")
    private String categoryName;

    @NotFound(action = NotFoundAction.IGNORE)
    @ManyToOne
    @JsonIgnore
    @JoinColumn(name = "parent_category_id")
    private FetchSubCategory mainCategory;

    @JsonSerialize(include = JsonSerialize.Inclusion.NON_EMPTY)//Avoiding empty json arrays.objects
    @OneToMany(mappedBy = "mainCategory", fetch = FetchType.EAGER)
    private List<FetchSubCategory> subCategory;

    public Integer getCategoryId() {
        return categoryId;
    }

    public void setCategoryId(Integer categoryId) {
        this.categoryId = categoryId;
    }

    public String getCategoryName() {
        return categoryName;
    }

    public void setCategoryName(String categoryName) {
        this.categoryName = categoryName;
    }

    public FetchSubCategory getMainCategory() {
        return mainCategory;
    }

    public void setMainCategory(FetchSubCategory mainCategory) {
        this.mainCategory = mainCategory;
    }

    public List<FetchSubCategory> getSubCategory() {
        return subCategory;
    }

    public void setSubCategory(List<FetchSubCategory> subCategory) {
        this.subCategory = subCategory;
    }

获取您的子类别

public List<FetchSubCategory> fetchSubCategory() throws SQLException, ClassNotFoundException, IOException {
        List<FetchSubCategory> groupList = null;
        try {
            Session session = sessionFactory.getCurrentSession();
            Query query = session.createQuery("select distinct e FROM FetchSubCategory e INNER JOIN e.subCategory m ORDER BY m.mainCategory");
            groupList = query.list();
        } catch (Exception e) {
            e.printStackTrace();
        }

        return groupList;
    }

【讨论】:

  • 如果我们希望这种关系成为 OnetoOne 怎么办?代码看起来如何
猜你喜欢
  • 1970-01-01
  • 2013-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-04
  • 2014-01-11
  • 1970-01-01
  • 2021-02-12
相关资源
最近更新 更多