`
piperzero
  • 浏览: 3474230 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
文章分类
社区版块
存档分类
最新评论

Hibernate读书笔记-----Hibernate的关联映射之1-1关联映射

 
阅读更多

二、11

无论是单向1-1映射关联,还是双休1-1映射关联,都有三种映射策略:基于主键、基于外键、采用连接表。

1、单向1-1映射关联

1.1、基于主键的单向1-1映射关联

对于基于主键的单向1-1关联,基于主键关联的持久化类不能拥有自己的主键生成器策略,它的主键由关联实体来负责生成。

是根据他自己的person属性来获得的。即他通过自身的一个getPerson()方法来获得Person对象。然后通过Person对象中的getID()方法获得id,然后赋值给自身id。这样就可以不需要自己来生成id

采用基于主键的1-1关联时,应使用<one-to-one.../>元素来映射关联实体,配置<one-to-one.../>元素时需要指定一个name属性。

实例(Person<--IDCard)

Person

public class Person {
	private Integer id;
	private String name;
	private IDCard idCard;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public IDCard getIdCard() {
		return idCard;
	}

	public void setIdCard(IDCard idCard) {
		this.idCard = idCard;
	}

}    

IDCard:

public class IDCard {
	private Integer id;
	private String useLife;
	public String getUseLife() {
		return useLife;
	}

	public void setUseLife(String useLife) {
		this.useLife = useLife;
	}

	private Person person;

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public Person getPerson() {
		return person;
	}

	public void setPerson(Person person) {
		this.person = person;
	}

}

映射文件:

Person.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="Person" table="person">
		<id name="id" column="personID">
			<generator class="native" />
		</id>
		
		<property name="name" column="personName" />	
	</class>
</hibernate-mapping>

IDCard.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="IDCard" table="idCard">
		<id name="id" column="idCardID">
			<!-- 基于主键关联时,主键生成策略是foreign,表明根据关联类的主键来生成该实体的主键 -->
			<generator class="foreign">
			    <!-- 指定引用关联实体的属性名  -->
				<param name="property">person</param>
			</generator>
		</id>
		
		<property name="useLife" column="useLife" />
		<one-to-one name="person" constrained="true" />	 
	</class>
</hibernate-mapping>

在上面的映射文件中,采用这种关联映射策略是,idCard表作为从表,此时idCard表的主键将没有自己的主键生成策略。他是根据person表中的主键来生成的。同时从表(idCard)里记录的主键将会与主表(person)里的记录保存一致。

IDCard中的id既是主键也是外键。那么idCard表如何通过person表来生成主键的呢?

foreign生成器中有一个元素:property。这个元素代表了该表的外键是从哪一个属性中获得的。通过上面的配置可以发现idCard表的外键是从person属性中获得的。它的外键就是通过person属性中的getId获得id,然后将该id直接赋给id。

使用constrained="true"表明该类对应表和被关联的对象所对应的数据库表之间通过一个外键引用对主键进行约束。

通过上面的配置后,就可以对两个实体进行操作了:

	static void add(){
		Session  session = null;
		Transaction tx = null;
		try{
			session = HibernateUtil.getSession();
			tx = session.beginTransaction();
			IDCard idCard = new IDCard();
			idCard.setUseLife("10年");
			
			Person person = new Person();
			person.setName("chentmt");
			
			idCard.setPerson(person); 
			session.save(person);
			session.save(idCard);
			tx.commit();
			
		}finally{
			if(session!=null)
				session.close();
		}
	}

1.2、基于外键的单向1-1映射关联

基于外键的关联映射与一般的N-1关联映射没有多大区别,只需要将<many-to-one.../>元素中增加unique="true"属性即可。如下:

<hibernate-mapping package="com.hibernate.domain">
	<class name="IDCard" table="idCard">
		<id name="id" column="idCardID">
			<generator class="native" />	
		</id>
		
		<property name="useLife" column="useLife" />
		
		<many-to-one name="person" column="personID" unique="true" />
	</class>
</hibernate-mapping>

unique="true"代表了idCard表的personid外键列上增加了唯一约束--这样就完成基于外键的单向1-1映射了。

其他的配置文件和持久化类都不需要做修改。

1.3、有连接表的单向1-1映射关联

和上面差不多,只需要在有连接表的N-1关联映射中的<many-to-one.../>元素增加一个unique="true"即可。如下:

<hibernate-mapping package="com.hibernate.domain">
	<class name="IDCard" table="idCard">
		<id name="id" column="idCardID">
			<generator class="native" />	
		</id>
		
		<property name="useLife" column="useLife" />
		<!-- 使用join元素强制使用连接表 -->
		<join table="person_idCard">
		 	<key column="idCardID"/>
		 	<many-to-one name="person" column="personID" unique="true"/>
		 </join>	
	</class>
</hibernate-mapping>


2、双向1-1关联映射

对于双向的1-1关联需要让两个持久化列都增加引用关联实体的属性,并为该属性提供settergetter方法。持久化类:如上。

2.1基于主键的双向1-1关联映射

基于主键的双向1-1关联映射同样需要在一端的主键生成器策略使用foreign策略,表明将根据对方的主键来生成自己的主键,本实体不能拥有自己的主键生成策略。另一端需要使用<one-to-one.../>元素用来映射关联实体,否则就变成了单向的。映射文件如下:

Person.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="Person" table="person">
		<id name="id" column="personID">
			<generator class="native" />
		</id>
		
		<property name="name" column="personName" />
		<!-- 映射关联实体 -->	
		<one-to-one name="idCard" />
	</class>
</hibernate-mapping>

IDCard.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="IDCard" table="idCard">
		<id name="id" column="idCardID">
		<!-- 基于主键关联时,主键生成策略是foreign,表明根据关联类的主键来生成该实体的主键 -->
			<generator class="foreign">
			    <!-- 指定引用关联实体的属性名  -->
				<param name="property">person</param>
			</generator>
		</id>
		
		<property name="useLife" column="useLife" />
		<one-to-one name="person" constrained="true" />
	</class>
</hibernate-mapping>

对于操作这个两个实体增加同时。因为可以通过两边来访问,所以这里就演示查询

这里查询分为两种:基于主表查询和基于从表查询

基于主表查询(通过主表查询从表记录)

	static void query(int personid){
		Session  session = null;
		try{
			session = HibernateUtil.getSession();
			
			Person person = (Person) session.get(Person.class, personid);
			System.out.println("useLife="+person.getIdCard().getUseLife());	
		}finally{
			if(session!=null)
				session.close();
		}
	}

我们知道对于N-1关联查询的时候,系统会产生两条sql查询语句来检索从表对象:一条先查询主表,然后根据外键从从表中获取相对应的记录。但是对于1-1关联时,它并不是产生两条sql语句来查询。而是一条sql语句,通过外连接来连接两张表的。如下

Hibernate: select person0_.personID as personID1_1_, person0_.personName as personName1_1_, idcard1_.idCardID as idCardID2_0_, idcard1_.useLife as useLife2_0_ from person person0_ left outer join idCard idcard1_ on person0_.personID=idcard1_.idCardID where person0_.personID=?

基于从表查询(通过从表查询主表)

	static void query(int personid){
		Session  session = null;
		try{
			session = HibernateUtil.getSession();
			
			IDCard idCard = (IDCard) session.get(IDCard.class, 1);
			System.out.println(idCard.getPerson().getName());
		}finally{
			if(session!=null)
				session.close();
		}
	}

通过从表查询主表与通过主表查询从表又有点不同了。在这里它不再是产生一条sql语句,而是两条。如下:

Hibernate: select idcard0_.idCardID as idCardID2_0_, idcard0_.useLife as useLife2_0_ from idCard idcard0_ where idcard0_.idCardID=?

Hibernate: select person0_.personID as personID1_1_, person0_.personName as personName1_1_, idcard1_.idCardID as idCardID2_0_, idcard1_.useLife as useLife2_0_ from person person0_ left outer join idCard idcard1_ on person0_.personID=idcard1_.idCardID where person0_.personID=?

它会先查询从表,获取记录,然后再通过外连接方式连接两张表根据personID获取记录。

2.2基于外键的双向1-1关联映射

对于基于外键的双向1-1关联映射。外键可以存放任意一边。需要存放外键的一端,需要增加<many-to-one../>元素。同时也需要添加unique="true"属性。

对于双向单位1-1关联映射,两个实体原本是处于平等状态的。但是当我们选择一个表来增加外键后,该表就变成了从表,另一个表变成主表。

另一端需要使用<one-to-one../>元素,该元素需要使用name属性指定关联属性名,同时也需要使用property-ref属性来指定引用关联类的属性。property-ref的值是从表中的引用属性。

映射文件如下:

Person.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="Person" table="person">
		<id name="id" column="personID">
			<generator class="native" />
		</id>
		
		<property name="name" column="personName" />
		<!-- 映射关联实体 -->	
		<one-to-one name="idCard" 	property-ref="person"/>
	</class>
</hibernate-mapping>

IDCard.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="IDCard" table="idCard">
		<id name="id" column="idCardID">
			<generator class="native" />	
		
		</id>
		
		<property name="useLife" column="useLife" />
		<many-to-one name="person" column="personID" unique="true" />
	</class>
</hibernate-mapping>

2.3有连接表的双向1-1关联映射

采用这个方式是非常少的,因为这中情况映射相当复杂,数据模型繁琐,一般不推荐采用这种策略。

双向1-1关联两端都需要使用<join.../>元素指定连接表,<join../>元素的table属性用于指定连接表的表名,所有两端的table属性值应该是一致的。同时两个也需要增加key元素映射连接表的外键列,还需要增加<many-to-one../.>元素映射关联属性,两个<many-to-one.../>元素都需要增加unique="true"属性。注意这里两端的key元素和<many-to-one../>column的属性值应该是相反的。

同时为了让hibernate在连接表的两个数据列上增加唯一约束,映射文件应该为两个<key.../>元素指定unique="true"

当使用连接表来建立1-1关联关系时,两个实体应该是绝对的平等,不存在任何的主从约束关系,hibernate映射他们的连接表时,将会选择某一个外键作为连接表的主键--因此两个持久化类的映射文件依然不是完全相同的。映射文件必须在一端的<join.../>元素中指定inverse="true",而另一端则指定option="true"。下面是两个映射文件

Person.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="Person" table="person">
		<id name="id" column="personID">
			<generator class="native" />
		</id>
		
		<property name="name" column="personName" />
		
		<join table="person_idCard" inverse="true">
			<key column="personID" unique="true" />
			<many-to-one name="idCard" column="idCardID" unique="true" />
		</join> 
	</class>
</hibernate-mapping>

IDCard.hbm.xml

<hibernate-mapping package="com.hibernate.domain">
	<class name="IDCard" table="idCard">
		<id name="id" column="idCardID">
			<generator class="native" />	
		</id>
		
		<property name="useLife" column="useLife" />
		<join table="person_idCard" optional="true">
			<key column="idCardID" unique="true" />
			<many-to-one name="person" column="personID" unique="true"></many-to-one>
		</join>
	</class>
</hibernate-mapping>


分享到:
评论

相关推荐

    Hibernate映射笔记

    hibernate配置关系的笔记

    J2EE三大框架_笔记_a

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    J2EE框架_笔记_c

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    hibernate学习笔记

    Hibernate 学习笔记 1 第一个hibernate项目(hibernate_first) 2 测试实体对象的生命周期(hibernate_session) 3 hibernate基本映射(hibernate_basemapping) 4 class实体类---表 4 标签id 5 主键生成器Generator 6...

    J2EE框架_笔记_b

    J2EE三大框架_笔记 共分三块: J2EE框架_笔记_a: 1-JSP+JDBC_假分页笔记 2-JSP+JDBC_真分页(基于Oracle数据库分页)笔记 3-JSP+DAO和MVC+DAO(基于MySQL数据库分页...54留言管理程序_Struts + Spring + Hibernate笔记

    JPA学习笔记-EJB-04JPA关联映射总结

    感觉JPA关联映射实现感觉比Hibernate配置文件的关联映射几乎一样,只是引入了“零配置”这个概念。劣者自己在做一个东西的时候用到了关联映射,在此将它做一个总结。留给自己回顾用。

    Hibernate_容器映射技术笔记

    Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记Hibernate_容器映射技术笔记

    Hibernate学习笔记

    001 Hibernate 简介(开源 O/R 映射框架) 002 第一个 Hibernate 示例 003 hibernate 主要接口介绍 004 持久对象的生命周期介绍 005 query 接口初步 006 开源 O/R 映射框架内容回顾 007 Hibernate 基本映射标签和属性...

    javaEE框架笔记,识货人下

    54留言管理程序_Struts + Spring + Hibernate笔记.pdf 6-Struts标签-BEAN标签笔记.pdf 7-Struts标签 -LOGIC标签笔记.pdf 8-Struts标签- HTML标签笔记.pdf 9-Struts高级部分(1)(解决重复提交、上传组件)笔记.pdf

    hibernate笔记

    1 下载hibernate-distribution-3.3.2.GA-dist 5 2 下载hibernate-annotations-3[1].4.0.GA 5 3 注意阅读hibernate compatibility matrix(hibernate 网站download) 5 4 下载slf4jl.5.8 6 Hibernate HelloWorld 6 1 ...

    Hibernate中单一映射笔记

    Hibernate开发过程(单一映射体) 1创建持久类XXXX.java(要有oid字段:唯一且不具有业务含义;所有属性都有getter/setter方法;空的构造方法;不含oid的构造方法) 2创建映射文件XXXX.hbm.xml(包,类,id,字段) 3...

    Hibernate学习笔记和资料

    hibernate概述,hibernate入门Demo,hibernate配置文件详解(全局配置,实体类映射配置),配置实体规则,核心API详解(Configuration,sessionFactory,session,Transaction),hibernate中的对象状态以及刷新能缓存机制 ...

    Hibernate笔记 马士兵

    第9课 Hibernate的重点学习:Hibernate的对象关系映射 12 一、对象---关系映射模式 12 二、常用的O/R映射框架: 13 第10课 模拟Hibernate原理(OR模拟) 13 一、 项目名称 13 二、 原代码 13 第11课 Hibernate基础配置...

    hibernate初学者笔记

    关于hibernate的Session,向数据插入时的事务隔离级别,持久化对象的状态,对应关系的映射文件,表与表之间的多种映射关系,以及hibernate的二级缓存的笔记。

    Spring和Hibernate学习笔记

    第四课:hibernate多对一关联映射 ...................... Spring: 第一课:构建Spring的环境并建立一个例子 第三课:spring Bean的作用域 第四课:spring对AOP的只是(采用Annotation的方式) 第五课:spring对AOP...

    Hibernate学习笔记_songjignhao_1

    自己记录的学习笔记,内容很详细,有代码,包括:一对多双向关联关系、一对多双向自身关联关系、一对一关联关系(主键关联、外键关联)、一对多与一对一结合、多对多关联关系、Map、Set、List与Bag映射关系、查询...

    Hibernate - 学习笔记

    使用Hibernate对数据进行操作时会牵涉到3种类型的文件:Java类(实体类),映射文件(test.hbm.xml),数据库的表结构(表结构的创建).从理论上说只要知道其中一个,另外两个就可以从知道的那个文件中生成出来,这就涉及到先...

    Hibernate3 学习笔记.ppt

    Hibernate3 学习笔记.ppt ...三、Hibernate映射申明(Mapping declaration) 四、Hibernate Annotations 五、持久化对象的状态和生命周期 六、Hibernate查询 七、Hibernate最佳实践 八、Hibernate Tool

    Hibernate实体映射

    里面包含Hibernate实体映射的具体实例代码,还有相关教程笔记,喜欢的可以学习学习。

    Hibernate学习笔记(1)

    Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端...

Global site tag (gtag.js) - Google Analytics