您的位置:首页 > 其它

Hibernate映射(三)— 一对一

2015-05-30 22:07 471 查看
两种策略:
主键关联:两个对象有相同的主键值,通过表的主键来关联
唯一外键关联:本是用于多对一的配置,若加上那个唯一的限制后,也可用来表示一对一关联关系



主键:

1、单向
情况:
一个人有一个***,人知道***,***不知道人(人来维护关系)
原理:让两个实体的主键一样,就不需要加入多余字段
关系图:



<span style="font-size:18px;">实体:
		Card:
			public class IdCard {
				
				private int id;
				
				private String cardNo;
				
				public int getId() {
					return id;
				}
			
				public void setId(int id) {
					this.id = id;
				}
			
				public String getCardNo() {
					return cardNo;
				}
			
				public void setCardNo(String cardNo) {
					this.cardNo = cardNo;
				}
			}
			
		Person:
			public class Person {
			
				private int id;
				
				private String name;
				
				private IdCard idCard;
			
				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 IdCard getIdCard() {
					return idCard;
				}
			
				public void setIdCard(IdCard idCard) {
					this.idCard = idCard;
				}
			}
			
	</span>
<span style="font-size:18px;">映射文件:
		Card:
			<hibernate-mapping>
				<class name="com.bjpowernode.hibernate.IdCard" table="t_idcard">
					<id name="id">
						<generator class="native"/>
					</id>
					<property name="cardNo"/>
				</class>
			</hibernate-mapping>
			
		Person:
			<hibernate-mapping>
				<class name="com.bjpowernode.hibernate.Person" table="t_person">
					<id name="id">
						<!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
						<generator class="foreign">
							<!-- property只关联对象 -->
							<param name="property">idCard</param>
						</generator>
					</id>
					<property name="name"/>
					
					<one-to-one name="idCard" constrained="true"/>
				</class>
			</hibernate-mapping>
	注:
		使用foreign生成策略,foreign会取得对象的标识
		property指关联对象
		one-to-one:默认主键加载,根据对端的主键来加载关联对象
		Constrained="true":当前主键(person的主键)还是一个外键参照了对端的主键(IdCard的主键),也就会生成外键约束语句
	</span>
<span style="font-size:18px;">客户端:
		public void testSave1() {
				Session session = null;
				try {
					session = HibernateUtils.getSession();
					session.beginTransaction();
					
					IdCard idCard = new IdCard();
					idCard.setCardNo("1111111111111111");
					
					Person person = new Person();
					person.setName("张三");
					//建立关联
					person.setIdCard(idCard);
					
					//没有抛出TransientObjectException
					//是由一对一关联映射的特性决定的,它必须先保存关联对象IdCard
					//这样它采用foreign映射策略才能取得关联对象的标识
					//也就是它默认了cascade属性
					session.save(person);
					
					session.getTransaction().commit();
					
				}catch(Exception e) {
					e.printStackTrace();
					session.getTransaction().rollback();
				}finally {
					HibernateUtils.closeSession(session);
				}
			}	
</span>



2、双向
情况:
一个人有一个***,人知道***,***知道人(人来维护关系)
双向就没有箭头



需要在IdCard加入<one-to-one>,指示hibernate将关联对象Person根据主键加载上来
实体:
		Card:
			public class IdCard {
				
				private int id;
				
				private String cardNo;
				
				private Person person;
			
				public int getId() {
					return id;
				}
			
				public void setId(int id) {
					this.id = id;
				}
			
				public String getCardNo() {
					return cardNo;
				}
			
				public void setCardNo(String cardNo) {
					this.cardNo = cardNo;
				}
			
				public Person getPerson() {
					return person;
				}
			
				public void setPerson(Person person) {
					this.person = person;
				}
			}
			
		Person:
			public class Person {
			
				private int id;
				
				private String name;
				
				private IdCard idCard;
			
				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 IdCard getIdCard() {
					return idCard;
				}
			
				public void setIdCard(IdCard idCard) {
					this.idCard = idCard;
				}
			}
			
	映射文件:
		Card:
			<hibernate-mapping>
				<class name="com.bjpowernode.hibernate.IdCard" table="t_idcard">
					<id name="id">
						<generator class="native"/>
					</id>
					<property name="cardNo"/>
					<one-to-one name="person"/>
				</class>
			</hibernate-mapping>
			
		Person:
			<hibernate-mapping>
				<class name="com.bjpowernode.hibernate.Person" table="t_person">
					<id name="id">
						<!-- 采用foreign生成策略,forgeign会取得关联对象的标识 -->
						<generator class="foreign">
							<!-- property只关联对象 -->
							<param name="property">idCard</param>
						</generator>
					</id>
					<property name="name"/>
					
					<one-to-one name="idCard" constrained="true"/>
				</class>
			</hibernate-mapping>
	客户端:
		public void testSave2() {
			Session session = null;
				try {
					session = HibernateUtils.getSession();
					session.beginTransaction();
					
					Person person = new Person();
					person.setName("张三");
		
					IdCard idCard = new IdCard();
					idCard.setCardNo("1111111111111111");
					idCard.setPerson(person);
					
					session.save(idCard);
					session.getTransaction().commit();
				}catch(Exception e) {
					e.printStackTrace();
					session.getTransaction().rollback();
				}finally {
					HibernateUtils.closeSession(session);
				}
		}


结果:



唯一外键

1、单向
原理:
多对一的特例,采用<many-to-one>标签来映射,指定多的一端为unique为true,这样就限制了多的一端的多重性的唯一
实体:
		IdCard:
			public class IdCard {
				
				private int id;
				
				private String cardNo;
				
				public int getId() {
					return id;
				}
			
				public void setId(int id) {
					this.id = id;
				}
			
				public String getCardNo() {
					return cardNo;
				}
			
				public void setCardNo(String cardNo) {
					this.cardNo = cardNo;
				}
			}
			
		person:
			public class Person {
			
				private int id;
				
				private String name;
				
				private IdCard idCard;
			
				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 IdCard getIdCard() {
					return idCard;
				}
			
				public void setIdCard(IdCard idCard) {
					this.idCard = idCard;
				}
			}
	映射文件:
		IdCard:
		          <hibernate-mapping>
				<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
					<id name="id">
						<generator class="native"/>
					</id>
					<property name="cardNo"/></class>
			</hibernate-mapping>
		Person:
			<hibernate-mapping>
				<class name="com.bjpowernode.hibernate.Person" table="t_person">
					<id name="id">
						<generator class="native"/>
					</id>
					<property name="name"/>
					<many-to-one name="idCard" unique="true"/>
				</class>
			</hibernate-mapping>
	客户端:
		public void testSave1() {
				Session session = null;
				try {
					session = HibernateUtils.getSession();
					session.beginTransaction();
					
					IdCard idCard = new IdCard();
					idCard.setCardNo("1111111111111111");
					Session.save(idCard);
					
					Person person = new Person();
					person.setName("张三");
					//建立关联
					person.setIdCard(idCard);
		
					//抛出TransientObjectException
					//因为IdCard为Transient状态
					session.save(person);
					
					session.getTransaction().commit();
				}catch(Exception e) {
					e.printStackTrace();
					session.getTransaction().rollback();
				}finally {
					HibernateUtils.closeSession(session);
				}
			}
结果:



2、双向

原理:采用<one-to-one>标签映射,必须指定<one-to-one>标签中的property-ref属性为关系字段的名称。使用单向一对一理念,idCard指定person外键关联为idCard即可
关系图:



<span style="font-size:18px;">	实体:
			IdCard:
				public class IdCard {
					
					private int id;
					
					private String cardNo;
					
					private Person person;
				
					public int getId() {
						return id;
					}
				
					public void setId(int id) {
						this.id = id;
					}
				
					public String getCardNo() {
						return cardNo;
					}
				
					public void setCardNo(String cardNo) {
						this.cardNo = cardNo;
					}
				
					public Person getPerson() {
						return person;
					}
				
					public void setPerson(Person person) {
						this.person = person;
					}
				}
				
			person:
				public class Person {
				
					private int id;
					
					private String name;
					
					private IdCard idCard;
				
					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 IdCard getIdCard() {
						return idCard;
					}
				
					public void setIdCard(IdCard idCard) {
						this.idCard = idCard;
					}
				}
		映射文件:
			IdCard:
			          <hibernate-mapping>
					<class name="com.bjpowernode.hibernate.IdCard" table="t_idCard">
						<id name="id">
							<generator class="native"/>
						</id>
						<property name="cardNo"/>
						<one-to-one name="person" property-ref="idCard"/>
					</class>
				</hibernate-mapping>
			Person:
				<hibernate-mapping>
					<class name="com.bjpowernode.hibernate.Person" table="t_person">
						<id name="id">
							<generator class="native"/>
						</id>
						<property name="name"/>
						<many-to-one name="idCard" unique="true"/>
					</class>
				</hibernate-mapping>
		客户端:
			public void testSave1() {
					Session session = null;
					try {
						session = HibernateUtils.getSession();
						session.beginTransaction();
						
						IdCard idCard = new IdCard();
						idCard.setCardNo("1111111111111111");
						Session.save(idCard);
						
						Person person = new Person();
						person.setName("张三");
						//建立关联
						person.setIdCard(idCard);
			
						//抛出TransientObjectException
						//因为IdCard为Transient状态
						session.save(person);
						
						session.getTransaction().commit();
					}catch(Exception e) {
						e.printStackTrace();
						session.getTransaction().rollback();
					}finally {
						HibernateUtils.closeSession(session);
					}
				}	</span>


结果:



小结:唯一外键关联单向和双向都是一样的,都是加个外键,影响的只是对象模型
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: