树状自关联 hibernate配置,查询

这篇博客介绍了如何在Hibernate中配置树状自关联,特别是处理栏目实体中的一级栏目与子栏目关系。通过配置,可以直接根据ID获取完整的栏目层级结构。测试代码显示了查询过程,数据库数据证实了配置的有效性,注意在使用时正确设置标注的范围。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

栏目实体
每个栏目有多个子栏目,一个父栏目
一级栏目无父栏目
hibernate配置

package com.france.bean;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OrderBy;
import javax.persistence.Table;

import org.hibernate.annotations.DynamicInsert;
import org.hibernate.annotations.DynamicUpdate;

@Entity
@Table(name = "lanmu")
@DynamicUpdate(true)
@DynamicInsert(true)
public class Lanmu implements java.io.Serializable {
    /**
     * 栏目 自关联一对多
     */
    private static final long serialVersionUID = 862821212669955478L;
    private Integer id;
    private String name;
    private String description;
    private Lanmu parentLanmu;
    private Integer level;
    private Set<Lanmu> children = new HashSet<Lanmu>(0);
    public Lanmu() {

    }
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "lanmu_id", unique = true, nullable = false)
    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "parentLanmu", nullable = true)
    public Lanmu getParentLanmu() {
        return parentLanmu;
    }
    public void setParentLanmu(Lanmu parentLanmu) {
        this.parentLanmu = parentLanmu;
    }
    public Integer getLevel() {
        return level;
    }
    public void setLevel(Integer level) {
        this.level = level;
    }
    @OneToMany(targetEntity=Lanmu.class, mappedBy="parentLanmu", cascade=CascadeType.ALL, fetch = FetchType.EAGER)  
    @OrderBy("name")
    public Set<Lanmu> getChildren() {
        return children;
    }
    public void setChildren(Set<Lanmu> children) {
        this.children = children;
    }

}

查询的时候 本来是参考
MySQL中进行树状所有子节点的查询
但是hibernate已经在对象映射做好了,所以直接根据id得到Lanu对象就可以

@Override
    public Lanmu findAllChildrenLanmu(int lanmu_id) {
        // TODO Auto-generated method stub
        Lanmu root=new Lanmu();
        root=lanmuDAO.get(Lanmu.class, lanmu_id);
        return root;
    }

测试代码:

    @Test
    public void testFindAllChildrenLanmu() {
        Lanmu root=service.findAllChildrenLanmu(1);
        System.out.println(root.getParentLanmu());//得到null
        System.out.println("get root ok");
        Set<Lanmu> c1=root.getChildren();
        Iterator iter=c1.iterator();
        while(iter.hasNext()){
            Lanmu l= (Lanmu)iter.next();
            System.out.printf("lanmu_id:%d,lanmu_name:%s\n",l.getId(),l.getName());
        }
    }

输出:

Hibernate: 
    select
        lanmu0_.lanmu_id as lanmu_id1_7_0_,
        lanmu0_.description as descript2_7_0_,
        lanmu0_.level as level3_7_0_,
        lanmu0_.name as name4_7_0_,
        lanmu0_.parentLanmu as parentLa5_7_0_,
        children1_.parentLanmu as parentLa5_7_1_,
        children1_.lanmu_id as lanmu_id1_7_1_,
        children1_.lanmu_id as lanmu_id1_7_2_,
        children1_.description as descript2_7_2_,
        children1_.level as level3_7_2_,
        children1_.name as name4_7_2_,
        children1_.parentLanmu as parentLa5_7_2_ 
    from
        lanmu lanmu0_ 
    left outer join
        lanmu children1_ 
            on lanmu0_.lanmu_id=children1_.parentLanmu 
    where
        lanmu0_.lanmu_id=? 
    order by
        children1_.name
 //得到二级栏目 一级栏目(1)和二级栏目节点(3,4)

Hibernate: 
    select
        children0_.parentLanmu as parentLa5_7_0_,
        children0_.lanmu_id as lanmu_id1_7_0_,
        children0_.lanmu_id as lanmu_id1_7_1_,
        children0_.description as descript2_7_1_,
        children0_.level as level3_7_1_,
        children0_.name as name4_7_1_,
        children0_.parentLanmu as parentLa5_7_1_ 
    from
        lanmu children0_ 
    where
        children0_.parentLanmu=? 
    order by
        children0_.name
        //得到三级栏目节点(null)(children0_.parentLanmu=3)
Hibernate: 
    select
        children0_.parentLanmu as parentLa5_7_0_,
        children0_.lanmu_id as lanmu_id1_7_0_,
        children0_.lanmu_id as lanmu_id1_7_1_,
        children0_.description as descript2_7_1_,
        children0_.level as level3_7_1_,
        children0_.name as name4_7_1_,
        children0_.parentLanmu as parentLa5_7_1_ 
    from
        lanmu children0_ 
    where
        children0_.parentLanmu=? 
    order by
        children0_.name
         //得到另一个三级栏目节点(5)(children0_.parentLanmu=4)
Hibernate: 
    select
        children0_.parentLanmu as parentLa5_7_0_,
        children0_.lanmu_id as lanmu_id1_7_0_,
        children0_.lanmu_id as lanmu_id1_7_1_,
        children0_.description as descript2_7_1_,
        children0_.level as level3_7_1_,
        children0_.name as name4_7_1_,
        children0_.parentLanmu as parentLa5_7_1_ 
    from
        lanmu children0_ 
    where
        children0_.parentLanmu=? 
    order by
        children0_.name
        //得到四级栏目节点(null)(children0_.parentLanmu=5)
null
get root ok
lanmu_id:3,lanmu_name:lanmuAA
lanmu_id:4,lanmu_name:lanmuAB

数据库数据

lanmu_iddescriptionlevelnameparentLanmu
1NULL1lanmuANULL
2NULL1lanmuBNULL
3NULL2lanmuAA1
4NULL2lanmuAB1
5NULL3lanmuABA4

最后,配置的时候注意fetch = FetchType.EAGER 的使用范围即可

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值