【Hibernate步步为营】--双向关联一对一映射具体解释(一)
一对一的映射在对象模型中是常常见到的,为了将对象模型转换为关系模型就必须在映射文件里进行配置,上篇文章讨论了一对一映射的单向关联的情况,重点是<one-to-one>标签的使用,须要在映射的主对象中加入该标签,并将该对象的主键设置为foreign这样就实现了主键关联映射。讨论完了单向接下来讨论双向映射。
一、双向主键关联
双向的主键关联事实上是单向一对一主键关联的一种特殊情况。仅仅只是要在关联对象的两端的映射文件里都要进行<one-to-one>的配置。另外还要在主映射的主键一端採用foreign外键关联属性。
这里相同使用Person和IdCard来讨论,一个人相应着一个唯一的身份证,并且一个身份证也唯一映射着一个人。所以这就产生了双向的关联关系。Person的主键相同也是IdCard的主键,各自是主键的同一时候也是外键,这样的关联关系成为双向一对一映射。表现到关系模型中可例如以下图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
图中的两个表採用了主键关联,person的主键是idCard的主键。所以它们之间构成了朱外键的约束关系,而且保证唯一性,映射到对象模型中。转变为person类和idCard类的一对一关系。例如以下图:
这样的一对一的关系上篇文章中也有讲到用的是<one-to-one>标签,另外这样的一对一映射又是双向的,所以要在两个对象之间同一时候配置<one-to-one>,首先来看idCard相应的类代码和映射文件代码。
1、IdCard相应的信息
IdCard.java类,IdCard类和Person类之间有一对一的关联关系所以要在IdCard类中加入相应的Person属性。这是为了能在映射文件里的外键中加入相应的属性,设置相应的外键关联类。
package com.src.hibernate; public class IdCard { //id属性
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
} //卡号属性
private String cardNo;
public String getCardNo() {
return cardNo;
}
public void setCardNo(String cardNo) {
this.cardNo = cardNo;
} //卡号相应的人
private Person person;
public Person getPerson(){
return person;
}
public void setPerson(Person person){
this.person=person;
}
}
IdCard.hbm.xml映射文件。在映射文件里加入外键属性person。并加入相应的<one-to-one>标签。目的是强制约束person类来实现一对一的映射关系,最后在映射中将constrained属性设为true,保证强制约束关系。
<? xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2014-5-15 23:47:00 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.src.hibernate.IdCard" table="IDCARD">
<id name="id" type="int" column="personId">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id> <property name="cardNo" type="string" column="cardno"></property>
<one-to-one name="person" constrained="true"></one-to-one>
</class>
</hibernate-mapping>
2、Person相应的信息
Person.java类。在该类中除了加入主要的属性外还要加入相应的IdCard类作为属性,由于它们之间是一对一的双向关联关系,所以在Person类中相同要加入IdCard类,相同的道理IdCard类中相同加入了Person类属性。
package com.src.hibernate; public class Person { //id号
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
} //姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
} //idCard
private IdCard idcard;
public IdCard getIdcard() {
return idcard;
}
public void setIdcard(IdCard idcard) {
this.idcard = idcard;
}
}
Person.hbm.xml映射文件,该文件里主键生成策略没有特殊的要求。由于它和IdCard类相互制约的关系,它的主键和外键都是IdCard的主键,另外由于是一对一关系所以要在映射文件里加入<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">
<!-- Generated 2014-5-15 23:47:00 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.src.hibernate.Person" table="PERSON">
<id name="id" type="int" column="personId">
<generator class="native"></generator>
</id> <property name="name" type="string" column="personName"></property>
<!--
one-to-one标签指示Hibernate怎样载入其关联对象。默认依据主键载入,也就是拿到关系字段值,依据对端的主键来载入关联对象
-->
<one-to-one name="idcard"></one-to-one>
</class>
</hibernate-mapping>
3、Hibernate映射文件
上面的类和映射文件配置好后接下来要在Hibernate.cfg.xml中配置与数据库映射的信息。须要将两个配置文件加入到Hibernate配置文件里。这样在生成相应的数据库时才干找到相应的生成项。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate_one2one_pk1</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1234</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <mapping resource="com/src/hibernate/Person.hbm.xml"/>
<mapping resource="com/src/hibernate/IdCard.hbm.xml" ></mapping>
</session-factory>
</hibernate-configuration>
4、生成结果
配置完毕后就能够将上面的内容生成对应的数据库了,在数据库中它会依照配置的内容生成对应的表结构,在表中有对应的外键和主键字段。生成表结构时Hibernate会在控制台输出对应的SQL语句,例如以下:
alter table IDCARD drop foreign key FK806F76ABAC038CD8
drop table if exists IDCARD
drop table if exists PERSON
create table IDCARD (personId integer not null, cardno varchar(255), primary key (personId))
create table PERSON (personId integer not null auto_increment, personName varchar(255), primary key (personId))
alter table IDCARD add index FK806F76ABAC038CD8 (personId), add constraint FK806F76ABAC038CD8 foreign key (personId) references PERSON (personId)
生成的表结构例如以下图:
在两张表中同一时候生成了personId主键,而且也是对应的外键,它同一时候限制约束了两张表的主键同样且唯一。
5、写入载入測试
5.1 写入測试
public void testSave1(){
Session session=null;
try{
//创建一个会话对象
session=HibernateUtils.getSession();
//开启会话事务
session.beginTransaction(); //创建person对象,并保存
Person person=new Person();
person.setName("zhangsan");
session.save(person); //创建idCard对象,并保存
IdCard idcard=new IdCard();
idcard.setCardNo("1111111111111");
idcard.setPerson(person);
session.save(idcard); //提交事务,改动数据库
session.getTransaction().commit(); }catch(Exception e){
//打印错误信息
e.printStackTrace();
//业务回滚
session.getTransaction().rollback();
}finally{
//关闭会话
HibernateUtils.closeSession(session);
}
}
插入的数据例如以下图:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
5.2 载入測试
public void testLoad1(){
Session session=null;
try{
//创建一个会话对象
session=HibernateUtils.getSession();
//开启会话事务
session.beginTransaction(); //获取person对象,并保存
Person person=(Person)session.load(Person.class,5);
System.out.println("IdCard.Id: "+person.getIdcard().getId());
System.out.println("IdCard.cardno: "+person.getIdcard().getCardNo()); //创建idCard对象,并保存
IdCard idcard=(IdCard)session.load(IdCard.class, 5);
System.out.println("Person.Id: "+idcard.getPerson().getId());
System.out.println("Person.name: "+idcard.getPerson().getName()); //提交事务。改动数据库
session.getTransaction().commit(); }catch(Exception e){
//打印错误信息
e.printStackTrace();
//业务回滚
session.getTransaction().rollback();
}finally{
//关闭会话
HibernateUtils.closeSession(session);
}
}
执行以上測试方法,在控制台打印的相关内容例如以下:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhhbmdfeGlueGl1/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
结语
【Hibernate步步为营】--双向关联一对一映射具体解释(一)的更多相关文章
- 【Hibernate步步为营】--多对多映射具体解释
上篇文章具体讨论了一对多映射,在一对多映射中单向的关联映射会有非常多问题,所以不建议使用假设非要採用一对多的映射的话能够考虑使用双向关联来优化之间的关系,一对多的映射事实上质上是在一的一端使用< ...
- 【Hibernate步步为营】--单向关联一对一映射
上篇文章对多对一的关联映射做了具体的分析,它在实现上能够有两种方式,而且这两种方式实现也非常easy,关键是标签<many-to-one>的使用,它分别指明了多端和一端的映射关系.这样的映 ...
- hibernate(四) 双向多对多映射关系
序言 莫名长了几颗痘,真TM疼,可能是现在运动太少了,天天对着电脑,决定了,今天下午花两小时去跑步了, 现在继上一章节的一对多的映射关系讲解后,今天来讲讲多对多的映射关系把,明白了一对多,多对多个人感 ...
- hibernate(六)一对一映射
关系映射是指对象之间的关系,并不是指数据库的关系,关系映射是解决当对象处于以下关系之一时,数据库表该如何映射的问题 (一)一对一单向外键关联 1.注解方式配置 创建一个Husband类和Wife类 H ...
- 【Hibernate步步为营】--映射合集汇总
前几篇文章具体讨论了对象模型到关系模型的转化方法,对映射关系做了具体的了解,Hibernate将对象模型转化为对应的关系模型是通过使用对应的映射来完毕的(相同也能够使用注解),对于对象之间的关系的转化 ...
- (Hibernate进阶)Hibernate映射——一对一双向关联映射(六)
上一篇博客我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息.如图所示: 关键原因在于对象模型具有方向性: 单向: ...
- Hibernate一对一双向关联映射
关键原因在于对象模型具有方向性: 单向:一端只能加载另一端,不能反过来. 双向:两端都可以加载另一端. 问题来了:如何我们想从身份证端(IdCard)加载人(Person),怎么办呢? 下面我们开始介 ...
- 【SSH进阶之路】Hibernate映射——一对一双向关联映射(六)
上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指仅仅能从人(Person)这端载入身份证端(IdCard),可是反过来.不能从身份 ...
- Hibernate一对多单向关联和双向关联映射方法及其优缺点 (待续)
一对多关联映射和多对一关联映射实现的基本原理都是一样的,既是在多的一端加入一个外键指向一的一端外键,而主要的区别就是维护端不同.它们的区别在于维护的关系不同: 一对多关联映射是指在加载一的一端数据的同 ...
随机推荐
- 怎么提高ArcGIS for Desktop10.x的性能
Esri新公布了一篇提高ArcGIS for Desktop10.x的性能的文章.大家能够关注一下 http://support.esri.com/en/knowledgebase/techartic ...
- ANR的一个实例分析
ANR是android经常出的超时提示,以前看过一个帖子,内容是mediaplayer在release的时候出的ANR,作者也是出了方法,什么加handler之类的. 最后都么有解决,咱们先看看那位同 ...
- 系统没有“internet信息服务(IIS)管理器”
系统没有“internet信息服务(IIS)管理器” | 浏览:8981 | 更新:2014-06-19 14:43 1 2 3 4 5 6 7 分步阅读 很多用户都在咨询:系统控制面板的管理工具中没 ...
- HDU 1394 Minimum Inversion Number (线段树 单点更新 求逆序数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1394 题意:给你一个n个数的序列,当中组成的数仅仅有0-n,我们能够进行这么一种操作:把第一个数移到最 ...
- linux串口编程总结
串口本身.标准和硬件 † 串口是计算机上的串行通讯的物理接口.计算机历史上,串口以前被广泛用于连接计算机和终端设备和各种外部设备.尽管以太网接口和USB接口也是以一个串行流进行数据传送的.可是串口连接 ...
- Queue 消息的发送与接收(PTP 消息传递模型)
上篇博客写到了JMS两种消息模型(P2P.pub/sub)<JMS两种消息模型>.本篇博客通过一个实例来进一步了解P2P模型. Queue消息的发送与接收--PTP消息传递模型,样例: Q ...
- [Cocos2d-x]CCSpriteBatchNode的使用
文档: http://cocos2d.cocoachina.com/document/index/class?url=dd/d95/classcocos2d_1_1_c_c_sprite_batch_ ...
- 《Pro Android Graphics》读书笔记之第三节
Android Frame Animation: XML, Concepts and Optimization Frame Animation Concepts: Cels, Framerate, a ...
- python语言学习1——初识python
Python是著名的“龟叔”Guido van Rossum在1989年圣诞节期间,为了打发无聊的圣诞节而编写的一个编程语言. 龟叔给Python的定位是“优雅”.“明确”.“简单”,所以Python ...
- hdu2151(递推dp)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2151 分析: DP.思路:全盘扫描. i表示时间,l表示第几棵树,方程: step[i ...