关闭

【hibernate】关联映射那些事(一)---单向N-1关联与单向1-1关联

193人阅读 评论(15) 收藏 举报
分类:

         前一段时间用一个小例子,来作为hibernate关联映射的一个入门。关联映射其实本身没有多难,只不过是关联关系比较多,从而让我们有点摸不到头脑,只要我们静下来心里,从一个更高的角度来看一看关联映射。我们一定会发现其实关联映射也就这么回事。

         所以从今天起,打算用几篇博客来好好总结一下hibernate的关联映射,在hibernate中关联映射也算是一个比较重要的知识点,所以更有必要好好总结一下。

        我们先来看看单向的关联映射

       单向的关联映射分为单向N-1映射,单向1-1映射,单向1-N映射,单向N-N映射。

       今天我们先来看看单向N-1映射

       在总结之前我们先来构造两个实体类。然后在通过这两个实体类来总结我们的关联关系。


           人实体类

           

public class Person {
	private int id;
	private String name;
	private int age;
	//yi
	private Address address;
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
}

          地址实体类

<span style="font-size:14px;">public class Address {
	private int addressId;
    private String Detail;
	
	public int getAddressId() {
		return addressId;
	}
	public void setAddressId(int addressId) {
		this.addressId = addressId;
	}
	public String getDetail() {
		return Detail;
	}
	public void setDetail(String detail) {
		Detail = detail;
	}
}</span>


单向N-1关联

      在讲解之前,我们先做这样一个前提:一个地址可以住着好多的人,一个人只能有一个地址。其中人就是N端,地址就是一端。

      单向N-1映射的关系由多的一端来维护,所以首先要在N的一端的实体中加入1端的引用。对于两个实体类就是person类单向的持有address的引用。

       所以在person类中我们加入了如下的代码。

private Address address;
	public Address getAddress() {
		return address;
	}
	public void setAddress(Address address) {
		this.address = address;
	}


无连接表的单向N-1映射(基于外键)

       无连接表表示的是不需要加入额外的一张关联表来保存person类和address类的关联,而是在N端加入1端的外键。在hibernate中使用<many –to-one>元素来映射N-1的关联关系,采用这样的关系,会在N的一端的数据表中加入一个外键列。

        下面我们看一下person类对应的映射文件。

    

<?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 >
	<class name="com.tgb.hibernate.Person" table="t_person">
		<id name="id" >
			<generator class="native"/>
		</id>
		<property name="name" />
		<property name="age" />
		<many-to-one name="address" class="Address" column="address_id" />
	</class>
</hibernate-mapping>

        在<many-to-one>元素中我们会看到这样几个基本的属性

         Name:该属性用来指定关联实体的属性。也指定1的一端是哪个类,在person类中我们定义了一个名为address的Address类型的属性。所以这个配置就为address。

         Class:该属性就是用来指定1端是哪个类。如果没有指定这个属性。那么hibernate会根据name属性,通过反射得到这个类。

         Column:用来指定外键列的列名。

 

Address类的映射文件并没有什么改变,就不做赘述。



 使用连接表的单向N-1映射

     使用连接表来建立单向N-1的关联关系,我们需要使用<join…/>元素来显式的将一个一个类的属性映射到多张表中,通常也用于强制使用连接表。

     下面看一下使用连接表时的映射文件

<?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 >
	<class name="com.tgb.hibernate.Person" table="t_person">
		<id name="id" column="person_id">
			<generator class="native"/>
		</id>
		<property name="name" />
		<property name="age" />
		<join table="t_person_address">
			<key column="person_id" />
		<many-to-one name="address" class="Address" column="address_id" />
		</join>
	</class>
</hibernate-mapping>

当使用join的时候,我是这样理解的,join显示声明了要将join中的字段生成一张表,然后我们就要设置这张表中的字段。首先我们需要将person_id,放进去,<many-to-one>元素要生成一个address_id 字段,放到person对应的表中,现在因为放到了join元素中,所以就生成到了t_person_address表中。

 

单向1-1关联

单向1-1关联,也分为基于外键的关联和使用连接表的关联,其中这两种方式就是在配置文件中将<many-to-one>元素中再增加一个属性 unique="true" ,使用该属性来表明主键的唯一性。这样就不会出现重复值,从而实现了1-1关联



下面说一说基于主键的1-1关联

       基于主键的单向1-1基于主键进行关联,基于主键关联的持久化类不能有自己的主键,它的主键由关联实体来负责生成,其主键生成策略使用foreign。采用这种映射方式,应该使用<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 >
	<class name="com.tgb.hibernate.Person" table="t_person">
		<id name="id" column="person_id">
		<!-- 基于主键关联时,主键生存策略为foreign,表明根据关联实体的主键来生成该实体的主键 -->
			<generator class="foreign">
				<param name="property">address</param>
			</generator>
		</id>
		<property name="name" />
		<property name="age" />
		<one-to-one name="address"  />
	</class>
</hibernate-mapping>
    


1
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    个人资料
    • 访问:66338次
    • 积分:10230
    • 等级:
    • 排名:第1636名
    • 原创:162篇
    • 转载:3篇
    • 译文:0篇
    • 评论:3418条
    博客专栏