6.Hibernate关系映射实例

关联关系

类与类之间最普通的关系就是关联关系,而且关联是有方向的

1. 建立单向多对一关联关系(对象)

(1).配置单向多对一关联

Dept类 (部门表)

  public class Dept implements Serializable{
 private Byte deptNo;   //部门编号
 private String deptName;	     //部门名称
 private String location;       //部门地址
 //GET SET 省略
}

Emp类(员工表 )

    public class Emp implements Serializable{
    	private Integer empNo;   //员工编号   
    	private String eName;     //员工姓名
    	private Dept dept;    //所属部门
	    //GET SET 省略
    	}

Dept.hbm.xml(部门类的配置类)

<hibernate-mapping>
	<class name="pojo.Dept" table="`DEPT`" schema="scott"
		dynamic-update="true">
		<id name="deptNo" column="`DEPTNO`" type="java.lang.Short">
			<generator class="increment" />
		</id>
		<property name="deptName" type="java.lang.String" column="`DNAME`" />
		<property name="location" type="java.lang.String" column="`LOC`" />
	</class>
</hibernate-mapping>

Emp.hbm.xml(员工类的配置类)

<hibernate-mapping>
	<class name="pojo.Emp" table="`EMP`" schema="scott"
		dynamic-update="true">
		<id name="empNo" column="`EMPNO`" type="java.lang.Integer">
			<generator class="increment" />
		</id>
		<property name="eName" type="java.lang.String" column="`ENAME`" />
		<property name="job" type="java.lang.String" column="`JOB`" />
		<property name="sal" type="java.lang.Double" column="`SAL`" />

		<property name="hireDate" type="java.util.Date" column="`HIREDATE`" />
		<many-to-one name="dept" column="`DEPTNO`"   
		class="pojo.Dept"></many-to-one>
		//column指的就是deot的外键,此处指的是EMP表的外键DEPTNO
	</class>
</hibernate-mapping>

(2).实现持久化操作

以插入为列

EmpDao中关键代码:

public void save(Emp emp) {
 	this.currentSession().save(emp);
 }

业务中的关键代码

public class EmpService {
 EmpDao empDao = new EmpDao();
 public void addNewEmp(Emp emp) {
 	Transaction tx = null;
 	Dept dept = null;
 	try {
 		tx = HibernateUtil.currentSession().beginTransaction();
 		empDao.save(emp);
 		tx.commit();
 	} catch (HibernateException e) {
 		e.printStackTrace();
 		if (tx != null) {
 			tx.rollback();
 		}
 	}
 }
}

测试方法的关键代码:

        Emp emp=new Emp();
		emp.seteName("张三");
		Dept dept=new Dept();
		dept.setDeptNo(new Short("10"));
		emp.setDept(dept);
		new EmpService().addNewEmp(emp);

测试类执行就可插入emp,dept各插入一条数据
也可做一些删除,查询的操作,这里就不一一举例了。

2. 建立双向一对多关联关系(集合)

上一大点建立了多对一,即多个用户属于一个部门,现在就是一对多的演示,即一个部门对应多个用户(以上实例为基础,修改)

(1).在Dept上加一个集合类型的emps属性


public class Dept implements Serializable{
   private Set<Emp> emps = new HashSet<Emp>();
   	public Set<Emp> getEmps() {
   	return emps;
   }
   public void setEmps(Set<Emp> emps) {
   	this.emps = emps;
   }
   }

(2).在Dept中加入set配置

<set name="emps" cascade="save-update">
   		<key column="`DEPTNO`"></key>
   		<one-to-many class="pojo.Emp" />
   	</set>
   	//key 对应表的外键
   	//定义set类型的原因是emps属性为java.util.Set集合类型

(3).双向关联关系下的增删改操作

1.cascade属性

cascade属性值 描述
none 默认,当session操作当前对象时,忽略其他关联的对象
save-update 当session的save(),update(),即saveOrUpdate()方法来保存或更新当前对象时,级联保存所有关联的瞬时状态的对象,并且级联更新所有关联的游离状态的对象
detele detele方法删除当前对象时,会级联删除所有关联的对象
all 包含save-update,delete的行为

对于cascade属性的认识:当属性值为none时,只能执行查询的操作;当属性值为save-update,就可以进行保存的操作,如果有主键,对数据库进行以主键update,如果没有主键直接进行save操作。如果属性值只是delete操作时,只可以进行删除的操作,那么all就可以进行任意操作

2.修改Dept.hbm.xml(设置cascade属性,进行删除的操作)

<set name="emps" cascade="save-update">
			<key column="`DEPTNO`"></key>
			<one-to-many class="pojo.Emp" />
		</set>

3.Deptdao 关键代码

public class DeptDao extends BaseDao {
	// 读取具体的Dept
	public Dept load(Serializable id) {
		return (Dept) currentSession().load(Dept.class, id);
	}
	// 删除
	public void load(Dept dept) {
		this.currentSession().delete(this.load(dept.getDeptNo()));
	}
}

4.业务类 关键代码


public class DeptService{
	DeptDao deptDao = new DeptDao ();

	public void deleteDept(Dept dept) {
		Transaction tx = null;
		try {
			tx = HibernateUtil.currentSession().beginTransaction();
			deptDao .delete(dept);
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		}
	}

5.测试类关键代码

Dept dept=new Dept();
dept.setDetpNo((byte)22);
new DeptService().deleteDept(dept);

运行该实例,hibernate会删除Dept对象及关联的Emp对象

> 元素的inverse属性 > 直译为反转,在Hibernate中,inverse属性指定了关联关系的方向。属性值有两个,即true,false,默认是false。关联关系中,inverse="false"为主动方,主动方会负责维护关联关系

3. 建立多对多关联关系(建立关系表)

以Project(项目表)和Emplyee(员工表),建立PROEMP表,表中设置项目表,员工表的外键,设置此表主键
(1).Project类

public class Project implements java.io.Serializable {
	private Integer proid;
	private String proname;
	private Set<Employee> employees = new HashSet<Employee>();
	//省略getter和setter方法
	}

(2).添加Project.hbm.xml的配置类

<set name="employees" table="`PROEMP`" cascade="save-update">
		<key column="`RPROID`"/>
		<many-to-many class="pojo.Employee" column="`REMPID`"/>
		</set>
		//key的column指定PROEMP的外键RPROID
		//many-to-many 的class属性指定集合中存放的是Employee对象,column属性指定PROEMP的外键RPROID

(3).ProjectDao的关键代码

	public void save(Project project) {
		this.currentSession().save(project);
	}

(4).ProjectService的关键代码

public void addNewProject(Project project) {
		Transaction tx = null;
		try {
			tx = HibernateUtil.currentSession().beginTransaction();
			projectDao.save(project);
			tx.commit();
		} catch (HibernateException e) {
			e.printStackTrace();
			if (tx != null) {
				tx.rollback();
			}
		}
	}

(5).测试类

Employee employee = new Employee(1, "张三");
		Employee employee2 = new Employee(2, "李四");
		Project project = new Project(3, "一号项目");
		Project project2 = new Project(4, "二号项目");

		project.getEmployees().add(employee);
		project.getEmployees().add(employee2);

		project2.getEmployees().add(employee);

		employee.getProjects().add(project);
		employee.getProjects().add(project2);
		employee2.getProjects().add(project);

		ProjectService projectService = new ProjectService();
		projectService.addNewProject(project);
		projectService.addNewProject(project2);

总结:多对多就是建立一个两个表之间想关联的一个表

4. 延迟加载

用于设定加载策略的lazy属性

级别 lazy属性值
类级别 元素中lazy属性的可选值为true(延迟加载)和false(立即加载)。默认true
一对多关联级别 元素的lazy属性可设置为true(延迟加载),extra(增强延迟加载)和false(立即加载).默认为true
多对一关联级别 <many-to-one》元素中的lazy属性的可选值为proxy(延迟加载),no-proxy(无代理延迟加载)和false(立即加载),默认为proxy

一般都设置延迟加载,设置立即加载存在两大不足:
1.执行不必要的查询语句,影响查询性能
2.加载不需要的对象,增强系统开销,浪费内存空间

猜你喜欢

转载自blog.csdn.net/qq_43051879/article/details/84258977