Hibernate笔记 5:实体关联关系:一对一

来自Wikioe
跳到导航 跳到搜索


关于

“一对一”的关系,可分为“主键关联”、“外键关联”。    ——【对应的数据库表结构不同】

键类型:

  1. 主键关联:两个实体使用相同的主键。
    Hibernate:实体关系:一对一(主键关联).png
    • 需要维护外键:一个实体的主键同时也是外键,参照于另一个实体的主键。
      • 所以,添加记录时,必须:先添加“实体A”,在添加“实体B”的记录。
  2. 外键关联:一个实体的主键用作另一个实体的外键。
    Hibernate:实体关系:一对一(外键关联).png


“一对一”的关系:同样还可分为“单项关联”、“双向关联”。

维护方式:

  1. 单项关联
    class A{
    	...
    	B b;
    }
    
    class B{
    	...
    }
    
    class A{
    	...
    }
    
    class B{
    	...
    	A a;
    }
    
  2. 双向关联:(常用)
    class A{
    	...
    	B b;
    }
    
    class B{
    	...
    	A a;
    }
    

关系维护:主键关联

缺点:
    由于两个实体的主键之间有外键参照关系,所以,增加记录时,必须先添加“非外键方”,然后才能添加“外键方”。

如下:Person 表的主键作为外键,必须先添加 IDCard 记录,再添加 Person 记录。

以“人”(Person)与“身份识别卡”(IDCard)为例:

  1. 一个人只能有一个身份识别卡;
  2. 一个身份识别卡也只能被指定给一个人;


以上一节的图为参考:IDCard 对应“实体 A”,Person 对应“实体 B”。

单项关联

示例:

在 Person 中维护 IDCard 对象;
public class Person{ 
	private int person_id;
	private String person_name;
	private String person_address;
	private String person_phone;

	// 维护识别卡对象
	private IDCard card;

	// getter、setter
	...
}
<hibernate-mapping>
	<class name="com.domain.Person" table="person">
		<id name="person_id" column="id">
			<!-- 主键生成策略“foreign”:申明该主键就是外键。并且指向 card 属性 -->
			<generator class="foreign">
				<param name="property">card</param>
			</generator>        
		</id>
		
		<property name="person_name" column="name"/>
		<property name="person_address" column="address"/>
		<property name="person_phone" column="phone"/>
		
		<!-- column:由于已申明主键即外键,所以省略。
			constrained:1、表明主键作为外键使用;2、级联关系的作用
		-->
		<one-to-one name="card" constrained="true"></one-to-one>
	</class>
</hibernate-mapping>

双项关联

示例:

  1. 在 Person 中维护 IDCard 对象;
    public class Person{ 
    	private int person_id;
    	private String person_name;
    	private String person_address;
    	private String person_phone;
    
    	// 维护识别卡对象
    	private IDCard card;
    
    	// getter、setter
    	...
    }
    
    <hibernate-mapping>
    	<class name="com.domain.Person" table="person">
    		<id name="person_id" column="id">
    			<!-- 主键生成策略“foreign”:申明该主键就是外键。并且指向 card 属性 -->
    			<generator class="foreign">
    				<param name="property">card</param>
    			</generator>
    		</id>
    		
    		<property name="person_name" column="name"/>
    		<property name="person_address" column="address"/>
    		<property name="person_phone" column="phone"/>
    		
    		<!-- column:由于已申明主键即外键,所以省略。
    			constrained:1、表明主键作为外键使用;2、级联关系的作用
    		-->
    		<one-to-one name="card" constrained="true"></one-to-one>
    	</class>
    </hibernate-mapping>
    
  2. 在 IDCard 中维护 Person 对象;
    public class IDCard{ 
    	private int card_id;
    	private String card_No;
    	private String card_state;
    
    	// 维护人对象
    	private Person person; 
    
    	// getter、setter
    	...
    }
    
    <hibernate-mapping>
    	<class name="com.domain.IdCard" table="idcard">
    		<id name="card_id" column="id">
    			<!-- 主键生成策略 -->
    			<generator class="native"/>
    		</id>
    		
    		<property name="card_No" column="No"/>
    		<property name="card_state" column="state"/>
    		
    		<!-- one-to-one:默认使用“主键关联”,所以没有 column -->
    		<one-to-one name="person"></one-to-one>
    	</class>
    </hibernate-mapping>
    

关系维护:外键关联

外键关联,就和其余关系(“一对多”、“多对多”)类似了。

可以将其看作是“一对多”的特例(“多端”为一)。

同样以上节关系为例。

单项关联

示例:

在 Person 中维护 IDCard 对象;
public class Person{ 
	private int person_id;
	private String person_name;
	private String person_address;
	private String person_phone;

	// 维护识别卡对象
	private IDCard card;

	// getter、setter
	...
}
<hibernate-mapping>
	<class name="com.domain.Person" table="person">
		<id name="person_id" column="id">
			<!-- 主键生成策略 -->
			<generator class="native"/>   
		</id>
		
		<property name="person_name" column="name"/>
		<property name="person_address" column="address"/>
		<property name="person_phone" column="phone"/>
		
		<!-- unique:指定此端(many)为一。如此将 many-to-one 标签用作 one-to-one -->
		<many-to-one name="card" column="card" unique="true"></many-to-one>
	</class>
</hibernate-mapping>

双项关联

示例:

  1. 在 Person 中维护 IDCard 对象;
    public class Person{ 
    	private int person_id;
    	private String person_name;
    	private String person_address;
    	private String person_phone;
    
    	// 维护识别卡对象
    	private IDCard card;
    
    	// getter、setter
    	...
    }
    
    <hibernate-mapping>
    	<class name="com.domain.Person" table="person">
    		<id name="person_id" column="id">
    			<!-- 主键生成策略 -->
    			<generator class="native"/>   
    		</id>
    		
    		<property name="person_name" column="name"/>
    		<property name="person_address" column="address"/>
    		<property name="person_phone" column="phone"/>
    		
    		<!-- unique:指定此端(many)为一。如此将 many-to-one 标签用作 one-to-one 
    			column:person 表的外键字段
            -->
    		<many-to-one name="card" column="cardID" unique="true"></many-to-one>
    	</class>
    </hibernate-mapping>
    
  2. 在 IDCard 中维护 Person 对象;
    public class IDCard{ 
    	private int card_id;
    	private String card_No;
    	private String card_state;
    
    	// 维护人对象
    	private Person person; 
    
    	// getter、setter
    	...
    }
    
    <hibernate-mapping>
    	<class name="com.domain.IdCard" table="idcard">
    		<id name="card_id" column="id">
    			<!-- 主键生成策略 -->
    			<generator class="native"/>
    		</id>
    		
    		<property name="card_No" column="No"/>
    		<property name="card_state" column="state"/>
    		
    		<!-- property-ref:指定关联 Person 类的 card 属性 -->
    		<one-to-one name="person" property-ref="card" class="domain1.Person"></one-to-one>
    	</class>
    </hibernate-mapping>