Hibernate多对一、双向关系、控制反转、级联配置

本文详细介绍了Hibernate中多对一关系的配置方法,包括配置文件、代码实现及性能对比,同时展示了双向关系配置及级联操作的优化。

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

Hibernate多对一关系配置

Students配置文件:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated May 24, 2016 4:29:13 PM by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
	<class name="Students" table="STUDENTS">
		<id name="sid" type="int">
			<column name="SID" />
			<generator class="increment" />
		</id>
		<property name="Sname" type="java.lang.String">
			<column name="SNAME" />
		</property>
		<property name="gender" type="java.lang.String">
			<column name="GENDER" />
		</property>

		<many-to-one name="grade" class="com.yonyou.hibernateentity.Grade"
			column="GID"></many-to-one>
	</class>
</hibernate-mapping>

Student类,持有一个班级类Grade,源代码请参考  Hibernate 单向一对多配置以及增删改查,但是班级类没有持有一个学生集合。

public class Students {
	private int sid;
	private String Sname;
	private String gender;
	private Grade grade;

	public Students() {
	}

	public Students(int sid, String sname, String gender) {
		super();
		this.sid = sid;
		Sname = sname;
		this.gender = gender;
	}
	

	public Students(String sname, String gender) {
		super();
		Sname = sname;
		this.gender = gender;
	}

	public int getSid() {
		return sid;
	}

	public void setSid(int sid) {
		this.sid = sid;
	}

	public String getSname() {
		return Sname;
	}

	public void setSname(String sname) {
		Sname = sname;
	}

	public String getGender() {
		return gender;
	}

	public void setGender(String gender) {
		this.gender = gender;
	}

	@Override
	public String toString() {
		return "Students [sid=" + sid + ", Sname=" + Sname + ", gender="
				+ gender + "]";
	}

	public Grade getGrade() {
		return grade;
	}

	public void setGrade(Grade grade) {
		this.grade = grade;
	}

	
}

测试代码:

<span style="white-space:pre">	</span>@Test
	public void testAdd() {
		Grade grade = new Grade("java一班", "java软件一班");
		Students stu = new Students("张三", "男");
		Students stu2 = new Students("李四", "女");
		//设置关联关系
		stu.setGrade(grade);
		stu2.setGrade(grade);
		Session session = HibernateUtil.getSession();
		Transaction transaction = session.beginTransaction();
		session.save(grade);
		session.save(stu);
		session.save(stu2);
		transaction.commit();
		HibernateUtil.closeSession(session);

	}
测试输出的sql,由于使用的主键策略是increment,看出来多方维护需要发送3个sql语句。

Hibernate: select max(GID) from GRADE
Hibernate: select max(SID) from STUDENTS
Hibernate: insert into GRADE (GNAME, GDESC, GID) values (?, ?, ?)
Hibernate: insert into STUDENTS (SNAME, GENDER, GID, SID) values (?, ?, ?, ?)
Hibernate: insert into STUDENTS (SNAME, GENDER, GID, SID) values (?, ?, ?, ?)


双向关系配置:需要在grade类加入一个set集合,存放students,grade配置参考  Hibernate 单向一对多配置以及增删改查

测试代码:

@Test
	public void testAdd() {
		Grade grade = new Grade("java一班", "java软件一班");
		Students stu = new Students("张三", "男");
		Students stu2 = new Students("李四", "女");
		// 设置关联关系
		grade.getSet().add(stu);
		grade.getSet().add(stu2);
		 stu.setGrade(grade);
		 stu2.setGrade(grade);
		Session session = HibernateUtil.getSession();
		Transaction transaction = session.beginTransaction();
		session.save(grade);
		 session.save(stu);
		 session.save(stu2);
		transaction.commit();
		HibernateUtil.closeSession(session);

	}

测试结果:发送了两条更新语句,效率不高。使用控制反转,由多端控制一端。减少sql语句发送。

<pre name="code" class="sql">Hibernate: select max(GID) from GRADE
Hibernate: select max(SID) from STUDENTS
Hibernate: insert into GRADE (GNAME, GDESC, GID) values (?, ?, ?)
Hibernate: insert into STUDENTS (SNAME, GENDER, GID, SID) values (?, ?, ?, ?)
Hibernate: insert into STUDENTS (SNAME, GENDER, GID, SID) values (?, ?, ?, ?)
Hibernate: update STUDENTS set GID=? where SID=?Hibernate: update STUDENTS set GID=? where SID=?

 在one方,控制反转 inverse=‘true’,测试结果: 

Hibernate: select max(GID) from GRADE
Hibernate: select max(SID) from STUDENTS
Hibernate: insert into GRADE (GNAME, GDESC, GID) values (?, ?, ?)
Hibernate: insert into STUDENTS (SNAME, GENDER, GID, SID) values (?, ?, ?, ?)
Hibernate: insert into STUDENTS (SNAME, GENDER, GID, SID) values (?, ?, ?, ?)

级联控制,级联包括 all,save-update,delete,none 默认为none

all,级联更新插入删除

save-update 更新,插入级联

delete级联删除

参考 :hibernate级联操作详解

级联操作

 一.简单的介绍

cascade和inverse (Employee – Department)

l  Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:

         none,all,save-update,delete, lock,refresh,evict,replicate,persist,

         merge,delete-orphan(one-to-many)。一般对many-to-one,many-to-many不设置级联,在<one-to-one>和<one-to-many>中设置级联。

l  inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。

         one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。

         注: 配置成one-to-one的对象不维护关联关系

二,属性的解析
class元素的lazy属性设定为true,表示延迟加载,如果lazy设为false,则
表示立即加载。以下对这二点进行说明。
     立即加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后,
            会立即再从数据库取得数据组装此对象所关联的对象(如学生证1)。
     延迟加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后,
            不会立即再从数据库中取得数据组装此对象所关联的对象(如学生1),
            而是等到需要时,才会从数据库取得数据组装此关联对象。
<one-to-one>元素的cascade属性表明操作是否从父对象级联到被关联的对象,     它
的取得可以是以下几种:
     none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联
          操作。它是默认值。
     save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,
          游离对象)。
     delete:在删除当前对象时,级联删除附属对象。
     all:所有情况下均进行级联操作,即包含save-update和delete操作。
     delete-orphan:删除和当前对象解除关系的附属对象。
<one-to-one>元素的fetch属性的可选值是join和select,默认是select。
当fetch属性设定为join时,表示连接抓取(Join fetching):Hibernate通过
在Select语句中使用outer join(外连接)来获得对象的关联实例或者关联集合。
当fetch属性设定为select时,表示查询抓取(Select fetching):需要另外发
送一条Select语句抓取当前对象的关联实体或集合。

三。代码练习

<set name="emps" cascade="save-update">
 <key column="depart_id"/>
  <one-to-many class="Employee"/>
</set>

<set name="students" table="taacher_student" inverse="true"><!-- table是用来指定中间表的属性 -->
<key column="teacher_id"></key><!-- 查找教师id时,链接中间表表的teacher_id -->
<many-to-many class="Student" column="student_id"></many-to-many>
</set>




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值