Hibernate框架中的关联映射

Hibernate技术学习 https://www.itkc8.com

一:什么是关联映射?

1:单向关联:只能通过一方(也称为主控方)找到另一方,反之则不能。

2:双向关联:通过关联的任一方都能够找到另一方。

3:不使用连接表的关联:在某一个表中定义一个外键字段,用于和另一个表中的主键进行关联,(侵入式设计方式)。

4:使用关联表的关联:通过定义另外一个表将两个表联系起来,在新定义表中的字段是被关联表中的主键字段,(非侵入式设计方式)。

定义关联关系:

1:在持久化类中,主控方持久化类持有关联对象,通常将受控方以属性的方式保存在对象中。

2:在映射关系中,使用one-to-one、one-to-many、many-to-one、many-to-many定义映射关系,而对于one-to-many、many-to-many需要使用集合持有。

 

二:单向多对一关联many-to-one

1:“多”方为主控方,主控方对象持有外键,通过持有外键找到与之对应的对象,”多“方对象包含一个与之关联的”一“方对象,这个对象以属性的方式存在对象中。

 

package com.goddog.bean;

import java.io.Serializable;

public class School implements Serializable{
	
	//"一方"
	private long schoolID;
	private String schoolName;
	private String schoolAddress;
	//此处省略了属性getter()和setter();
	
}
/**
 * 
 */
package com.goddog.bean;

import java.io.Serializable;

/**
 * @author HUXU
 *
 */
public class Student implements Serializable {
	
	//"多方"
	private long studentID;
	private String studentNumber;
	private String studentName;
	private School school;//Student(多端)通过属性school对School(一端)进行访问,因此,在持久化类Student中设置school属性
	//此处省略了属性getter()和setter();

}
<!-- School.hbm.xml -->
<hibernate-mapping package="com.goddog.bean">
    <class name="com.goddog.bean.School" table="T_SCHOOL" schema="goddog">
        <id name="schoolID" type="long">
        	<column name="SCHOOL_ID" precision="38" scale="0" />
            <generator class="sequence">
            	<param name="sequence">school_seq</param>
            </generator>
        </id>
		<property name="schoolName" type="string">
			<column name="SCHOOL_NAME" length="50" not-null="true"></column>
		</property>
		<property name="schoolAddress" type="string">
			<column name="SCHOOL_ADDRESS" length="100" not-null="true"></column>
		</property>
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Student.hbm.xml -->
<hibernate-mapping package="com.goddog.bean">
    <class name="com.goddog.bean.Student" table="T_STUDENT" schema="goddog">
        <id name="studentID" type="long">
        	<column name="STUDENT_ID" precision="38" scale="0" />
            <generator class="sequence">
            	<param name="sequence">student_seq</param>
            </generator>
        </id>
		<property name="studentNumber" type="string">
			<column name="STUDENT_Number" length="20" not-null="true"></column>
		</property>
		<property name="studentName" type="string">
			<column name="STUDENT_NAME" length="10" not-null="true"></column>
		</property>
		<many-to-one name="school" column="SCHOOL_ID"></many-to-one>
    </class>
</hibernate-mapping>

先创建one之后在创建many,这种是最佳实践

三:单向一对多关联(one-to-many)
1:就是多对一关联的逆向操作,外键方式(不推荐)和关系表方式(推荐)
2:以外键方式实现时,“一方”为主控方,“多方”对象持有外键,“一方”持久化类除了定义基本属性外,还需要定义一个集合类型的属性,
   “一方”通过集合属性找到与之对应的对象集合,在映射文件中,使用one-to-many定义一对多关系映射。

/**
 * @author HUXU
 * @category 单向一对多关联
 */
public class Schooldx implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private long schoolID;
	private String schoolName;
	private String schoolAddress;
	private Set<Studentdx> students = new HashSet<Studentdx>();
	//省略set()和get()方法<Studentdx>();
	//省略set()和get()方法
package com.goddog.bean;

import java.io.Serializable;

/**
 * @author HUXU
 * @category 单向一对多关联
 */
public class Studentdx implements Serializable{
	
	private long studentID;
	private String studentNumber;
	private String studentName;
	//省略set()和get()方法
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Schooldx.hbm.xml -->
<hibernate-mapping package="com.goddog.bean">
    <class name="com.goddog.bean.Schooldx" table="T_SCHOOL" schema="goddog">
        <id name="schoolID" type="long">
        	<column name="SCHOOL_ID" precision="38" scale="0" />
            <generator class="sequence">
            	<param name="sequence">school_seq</param>
            </generator>
        </id>
		<property name="schoolName" type="string">
			<column name="SCHOOL_NAME" length="50" not-null="true"></column>
		</property>
		<property name="schoolAddress" type="string">
			<column name="SCHOOL_ADDRESS" length="100" not-null="true"></column>
		</property>
		<set name="students">
			<key column="SCHOOL_ID"/>
			<one-to-many class="com.goddog.bean.Studentdx"/>
		</set>
    </class>
</hibernate-mapping>

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Studentdx.hbm.xml -->
<hibernate-mapping package="com.goddog.bean">
    <class name="com.goddog.bean.Studentdx" table="T_STUDENT" schema="goddog">
        <id name="studentID" type="long">
        	<column name="STUDENT_ID" precision="38" scale="0" />
            <generator class="sequence">
            	<param name="sequence">student_seq</param>
            </generator>
        </id>
		<property name="studentNumber" type="string">
			<column name="STUDENT_Number" length="20" not-null="true"></column>
		</property>
		<property name="studentName" type="string">
			<column name="STUDENT_NAME" length="10" not-null="true"></column>
		</property>
    </class>
</hibernate-mapping>

如果在<set>元素中增加inverse属性和cascade属性。cascade属性表示进行级联操作,其值可以为all、save-update、delete或none;inverse属性值为true时,表示由另一方维护关联关系,在本例中由"多"端维护关联关系。

 

<set name="students" inverse="true" cascade="all">
	<key column="SCHOOL_ID"/>
	<one-to-many class="com.goddog.bean.Studentdx"/>
</set>

 

四:双向的多对一关联

 

在实际应用中,双向多对一(双向一对多)关联映射经常被使用,双向多对一关联是单向多对一和单向一对多的组合。

 

/**
 * @author HUXU
 * @category 单向一对多关联
 */
public class Schooldx implements Serializable{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	private long schoolID;
	private String schoolName;
	private String schoolAddress;
	private Set<Studentdx> students = new HashSet<Studentdx>();
	//省略set()和get()方法<Studentdx>();
	//省略set()和get()方法
/**
 * 
 */
package com.goddog.bean;

import java.io.Serializable;

/**
 * @author HUXU
 *
 */
public class Student implements Serializable {
	
	//"多方"
	private long studentID;
	private String studentNumber;
	private String studentName;
	private School school;//Student(多端)通过属性school对School(一端)进行访问,因此,在持久化类Student中设置school属性
	//此处省略了属性getter()和setter();

}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Schooldx.hbm.xml -->
<hibernate-mapping package="com.goddog.bean">
    <class name="com.goddog.bean.Schooldx" table="T_SCHOOL" schema="goddog">
        <id name="schoolID" type="long">
        	<column name="SCHOOL_ID" precision="38" scale="0" />
            <generator class="sequence">
            	<param name="sequence">school_seq</param>
            </generator>
        </id>
		<property name="schoolName" type="string">
			<column name="SCHOOL_NAME" length="50" not-null="true"></column>
		</property>
		<property name="schoolAddress" type="string">
			<column name="SCHOOL_ADDRESS" length="100" not-null="true"></column>
		</property>
		<set name="students">
			<key column="SCHOOL_ID"/>
			<one-to-many class="com.goddog.bean.Studentdx"/>
		</set>
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Student.hbm.xml -->
<hibernate-mapping package="com.goddog.bean">
    <class name="com.goddog.bean.Student" table="T_STUDENT" schema="goddog">
        <id name="studentID" type="long">
        	<column name="STUDENT_ID" precision="38" scale="0" />
            <generator class="sequence">
            	<param name="sequence">student_seq</param>
            </generator>
        </id>
		<property name="studentNumber" type="string">
			<column name="STUDENT_Number" length="20" not-null="true"></column>
		</property>
		<property name="studentName" type="string">
			<column name="STUDENT_NAME" length="10" not-null="true"></column>
		</property>
		<many-to-one name="school" column="SCHOOL_ID"></many-to-one>
    </class>
</hibernate-mapping>

 

最佳实践:在双向关联中,在set标签中设置inverse="true"来表明自己不维护关系


五:多对多关联:(many-to-many)
1:在实现多对多关联时,只能采用连接表来完成,如学生表(STUDENT)、课程表(COURSE)、关系表(STUDENT_COURSE)。
2:单向多对多关联

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- StudentCourse.hbm.xml -->
<hibernate-mapping package="com.manytomany.bean">
    <class name="com.manytomany.bean.Student" table="T_STUDENT" schema="goddog">
        <id name="studentID" type="string">
        	<column name="STUDENT_ID" length="20" />
            <generator class="sequence">
            	<param name="sequence">student_seq</param>
            </generator>
        </id>
		<property name="studentNumber" type="string">
			<column name="STUDENT_NUMBER" length="50" not-null="true"></column>
		</property>
		<property name="studentName" type="string">
			<column name="STUDENT_NAME" length="100" not-null="true"></column>
		</property>
		<set name="course" table="STUDENT_ID" inverse="true" cascade="all">
			<key column="STUDENT_ID"/>  <!-- 主控方字段名 -->
			<many-to-many column="COURSE_ID" class="com.manytomany.bean.Course"></many-to-many>
		</set>
    </class>
    
    <class name="com.manytomany.bean.Course" table="T_COURSE" schema="goddog">
    	<id name="courseID" type="string">
    		<column name="COURSE_ID" length="20"/>
    		<generator class="sequence">
            	<param name="sequence">course_seq</param>
            </generator>
    	</id>
    	<property name="courseName" type="string">
    		<column name="COURSE_NAME" length="50" not-null="true"></column>
    	</property>
    </class>
</hibernate-mapping>


3:双向多对多关联
双向多对多关联和单向多对多关联的区别在于:双向多对多关联要在两个持久化类中声明关联到对方的属性如:private Set course=new HashSet();private Set students = new HashSet();还要在两个映射文件中配置<many-to-many>元素
最佳实践:只用使用了many-to-many在任意一段维护关系都非常的麻烦,所以在程序开发基本不会使用many-to-many,而是使用一个中间对象来完成两端的one-to-many
六:一对一关联
1:基于外键的一对一关联,很常用,属于多对一关联的特例
     基于外键的单向一对一关联用法基本与单向的多对一关联相同,只是多了unique="true"

 

<many-to-one name="" column="" cascade="all" not-null="true" unique="true"/>

     基于外键的双向一对一关联通过联合使用<many-to-one>和<one-to-one>元素进行配置,在每个持久化类中声明一个所关联的持久化类的对象,在没有配置关联映射的一方配置

                                     <one-to-one>元素,如

<one-to-one name="" class="" property-ref=""/>

其中property-ref属性值要和<many-to-one>元素中的name属性值保持一致,指定了所关联的对象。

 

2:基于主键的一对一关联,如:SCHOOL(学校表)、SCHOOLMASTER(校长表),关联的两个表共享一个主键SCHOOL_ID

     基于主键的单向一对一关联

 

/**
 * 
 */
package com.onetoone;

import java.io.Serializable;

/**
 * @author HUXU
 *
 */
public class School implements Serializable {
	private long schoolID;
	private String schoolName;
	private String schoolAddress;
	//此处省略set()和get()方法
}
/**
 * 
 */
package com.onetoone;

import java.io.Serializable;

/**
 * @author HUXU
 *
 */
public class SchoolMaster implements Serializable {
	private long schoolID;
	private String masterName;
	private School school;
	//此处省略了set()和get()方法
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- SchoolMaster.hbm.xml -->
<hibernate-mapping package="com.onetoone.bean">
    <class name="com.onetoone.bean.SchoolMaster" table="SCHOOLMASTER" schema="goddog">
        <id name="schoolID" type="long">
        	<column name="SCHOOL_ID" precision="38" scale="0" />
            <generator class="foreign">
            	<param name="property">school</param>
            </generator>
        </id>
		<property name="masterName" type="string">
			<column name="MASTER_NAME" length="50" not-null="true"></column>
		</property>
		<one-to-one name="school" class="com.onetoone.School" constrained="true" cascade="all"></one-to-one>
    </class>
</hibernate-mapping>

注意:foreign生成器有一个名称为property的参数,其值为持久化类SchoolMaster中声明的所关联的持久化类的对象。<one-to-one>元素的name属性值和foreign生成器的property参数值一致,class属性值为所关联的持久化类,constrained属性表示两个表之间是否存在约束关系,值为“true”表明SCHOOLMASTER表的主键同时作为外键和关联表的主键联系;
 

     基于主键的双向一对一关联(在另一方增加one-to-one)

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.onetoone.bean">
	
	<class name="com.onetoone.bean.School" table="SCHOOL" schema="goddog">
		<id name="schoolID" type="long">
			<column name="SCHOOL_ID" precision="38" scale="0"/>
			<generator class="assigned"></generator>
		</id>
		<property name="schoolName" type="string">
			<column name="SCHOOL_NAME" length="10" not-null="true"></column>
		</property>
		<property name="schoolAddress" type="string">
			<column name="SCHOOL_ADDRESS" length="10" not-null="true"></column>
		</property>
		<one-to-one name="schoolMaster" class="com.onetoone.bean.SchoolMaster" cascade="all"/>
	</class>
	
    <class name="com.onetoone.bean.SchoolMaster" table="SCHOOLMASTER" schema="goddog">
        <id name="schoolID" type="long">
        	<column name="SCHOOL_ID" precision="38" scale="0" />
            <generator class="foreign">
            	<param name="property">school</param>
            </generator>
        </id>
		<property name="masterName" type="string">
			<column name="MASTER_NAME" length="50" not-null="true"></column>
		</property>
		<one-to-one name="school" class="com.onetoone.School" constrained="true" cascade="none"></one-to-one>
    </class>
</hibernate-mapping>

 

 

基于关联表的一对一关联(极少用到),如学校表SCHOOL、地址表ADDRESS、学校-地址关联表SCHOOLADDRESS

 

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="com.onetoone.bean">
	
	<class name="com.onetoone.bean.School" table="SCHOOL" schema="goddog">
		<id name="schoolID" type="long">
			<column name="SCHOOL_ID" precision="38" scale="0"/>
			<generator class="sequence">
				<param name="sequence">school_seq</param>
			</generator>
		</id>
		<join table="SCHOOLADDRESS" optional="true">
			<key column="SCHOOL_ID" unique="true"/>
			<many-to-one name="address" column="ADDRESS_ID" not-null="true" unique="true"></many-to-one>
		</join>
	</class>
	
    <class name="com.onetoone.bean.Address" table="ADDRESS" schema="goddog">
        <id name="addressID" type="long">
        	<column name="ADDRESS_ID" precision="38" scale="0" />
            <generator class="sequence">
				<param name="sequence">address_seq</param>
			</generator>
        </id>
        <join table="SCHOOLADDRESS" optional="true" inverse="true">
        	<key column="ADDRESS_ID" unique="true"/>
        	<many-to-one name="school" column="SCHOOL_ID" not-null="true" unique="true"/>
        </join>
    </class>
    
</hibernate-mapping>

Hibernate技术学习 https://www.itkc8.com

 

 

 
 
 
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值