Hibernate的自身关联映射(十)

版权声明:转载请注明出处(两个蝴蝶飞) https://blog.csdn.net/yjltx1234csdn/article/details/87442418

非常对不起,老蝴蝶由于生活和工作上的事情太忙,无法及时更新,造成了将近三个月的停更。以后,会更加努力的。为了IT,加油。

上一章Hibernate的一对多映射的单向关联和双向关联(九),如果没有看过,请观看上一章

一. Hibernate的自身关联映射

这句话是什么意思呢? 简单理解就是,一个类自己进行相关联。 如部门Dept 类。 这个部门的父级部门有一个,也是部门,有多个子部门,也是部门。 还有科目类Subject,雇员类User, 即存在上下级的关系的。
这里用典型的Dept 类进行讲解。 在表结构中,应该表现出来的是,dept表后面有一个parentId 这个外键来自身关联。

二.搭建Hibernate环境,与前面相同。

三. 编写Dept实体类

package com.yjl.pojo;
import java.util.HashSet;
import java.util.Set;
/**
 @author: yuejl
 @date: 2019年2月16日 上午10:15:08
 @Description 数据库中一的一方 部门实体
*/
public class Dept {
	/**
	 * @param id 部门的编号
	 * @param name 部门的名称
	 * @param description 部门的描述
	 */
	private Integer id;
	private String name;
	private String description;
	/**
	 * @param parent 上级部门,只有一个
	 * @param children 下级 部门,可能存在多个,也可能 一个,或者没有。用Set
	 */
	private Dept parent;
	private Set<Dept> children=new HashSet<Dept>();
	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;
	}
	public Dept getParent() {
		return parent;
	}
	public void setParent(Dept parent) {
		this.parent = parent;
	}
	public Set<Dept> getChildren() {
		return children;
	}
	public void setChildren(Set<Dept> children) {
		this.children = children;
	}
	@Override
	public String toString() {
		return "Dept [id=" + id + ", name=" + name + ", description=" + description + "]";
	}
}

四. 编写对应的Dept.hbm.xml文件

<hibernate-mapping package="com.yjl.pojo" >
	<!-- 具体的实体类  由于前面指定了package包名。这里只需要写Dept即可。否则写com.yjl.pojo.Dept 全限定名称-->
	<class name="Dept" table="dept">
		<!-- 主键 -->
		<id name="id" column="id">
			<generator class="native"></generator>	
		</id>
		<!-- 其余属性  这里type运用的是java类型,并不是Hibernate和数据库的-->
		<property name="name" length="20" type="java.lang.String"></property>
		<property name="description" length="100" type="java.lang.String"></property>
		
		<!-- 对每一个字段进行分析。 先对parent进行分析。 多对一 -->
		<many-to-one name="parent" column="parentId" class="Dept"></many-to-one>
		<!-- 对children进行分析。 一对多 -->
		<set name="children">
			<!-- 与上面的many-to-one中的值保存一致 -->
			<key column="parentId"></key>
			<one-to-many class="Dept"/>
		</set>
	</class>
</hibernate-mapping>

五.编写测试的文件

五.一 测试保存的方法

/*自身关联的保存方法*/
	@Test
	public void saveTest(){
		Session session=HibernateUtil.getSession();
		/*1.创建数据,设置一级的*/
		Dept root=new Dept();
		root.setName("总裁室");
		/*2.设置二级的*/
		Dept d21=new Dept();
		d21.setName("财务室");
		Dept d22=new Dept();
		d22.setName("行政部");
		Dept d23=new Dept();
		d23.setName("管理部");
		/*3.设置三级的*/
		Dept d31=new Dept();
		d31.setName("开发部");
		Dept d32=new Dept();
		d32.setName("信息部");
		Dept d33=new Dept();
		d33.setName("人事部");
		/*4.设置关系*/
		d21.setParent(root);
		d22.setParent(root);
		d23.setParent(root);
		
		d31.setParent(d23);
		d32.setParent(d23);
		d33.setParent(d22);	
		/*保存。 从上到下保存*/
		session.save(root);
		session.save(d21);
		session.save(d22);
		session.save(d23);
		session.save(d31);
		session.save(d32);
		session.save(d33);
	}

运行之后,步骤是:

  1. 创建dept表
  2. 修改表结构,添加外键parentId
  3. 插入数据

在这里插入图片描述
其实,自身关联的配置与一对多的双向配置是一样的,但刚开始的时候,老蝴蝶并不明白,查了很多资料。相信有些人也不太明白,所以单独列了出来。

五.二 测试查询的方法

/*自身关联的查询*/
	@Test
	public void searchTest(){
		Session session=HibernateUtil.getSession();
		/*1 管理部做查询*/
		Dept d=session.get(Dept.class,4);
		System.out.println("自身查询:"+d);
		/*2 上级部门的*/
		Dept parent=d.getParent();
		System.out.println("上级部门的:"+parent);
		/*3 下级部门的*/
		Set<Dept> children=d.getChildren();
		System.out.println("下级部门的:");
		for (Dept dept : children) {
			System.out.println(dept);
		}
		/*4.上级部门的下级部门*/
		Set<Dept> children1=parent.getChildren();
		System.out.println("上级部门的下级部门的:");
		for (Dept dept : children1) {
			System.out.println(dept);
		}
	}

在这里插入图片描述
均是正常的查询。

五.三 扩充

  1. 在toString()方法中,添加输出parent 会怎么样?
    在这里插入图片描述
    正常。
  2. 只添加children 会怎么样?
    在这里插入图片描述
    也是正常的。
  3. 如果同时添加呢? 会形成一个死循环,也会造成栈溢出错误。
    在这里插入图片描述
    切记,在自身关联时,不要把parent和children属性同时输出。 扩大话就是,不一定要在toString()中输出全部的属性来表示这个对象,只需要输出几个标志性的即可。

谢谢!!!

猜你喜欢

转载自blog.csdn.net/yjltx1234csdn/article/details/87442418