009一对一 主键关联映射_单向(one-to-one)
009一对一 主键关联映射_单向(one-to-one)
² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号)
² 有两种策略可以实现一对一的关联映射
- 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联。
- 唯一外键关联:外键关联,本来是用于多对一的配置,但是如果加上唯一的限制之后,也可以用来表示一对一关联关系。
实例场景:人—-> 身份证号(PersonàIdCard),从IdCard看不到Person对象
对象模型(主键关联映射-单向):
(站在人的角度看)

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;//持有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;
}
}

因为是person引用idcard,所以idcard要求先有值。而person的主键值不是自己生成的。而是参考idcard的值,person即是主键,同时也是外键。
IdCard实体类的映射文件:
<hibernate-mapping>
<class name="com.wjt276.hibernate.IdCard" table="t_idcard">
<id name="id" column="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
</class>
</hibernate-mapping>
Persion实体类的映射文件:
<hibernate-mapping>
<class name="com.wjt276.hibernate.Person" table="t_person">
<id name="id" column="id">
<!--
因为主键不是自己生成的,而是作为一个外键(来源于其它值),所以使用foreign生成策略
foreign:使用另外一个相关联的对象的标识符,通常和<one-to-one>联合起来使用。
再使用元素<param>的属性值指定相关联对象(这里Person相关联的对象为idCard,则标识符为idCard的id)为了能够在加载person数据同时加载IdCard数据,所以需要使用一个标签<one-to-one>来设置这个功能。
-->
<generator class="foreign">
<!-- 元素<param>属性name的值是固定为property -->
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!-- <one-to-one>标签
表示如何加载它的引用对象(这里引用对象就指idCard这里的name值是idCard),同时也说是一对一的关系。
默认方式是根据主键加载(把person中的主键取出再到IdCard中来取相关IdCard数据。)
我们也说过此主键也作为一个外键引用 了IdCard,所以需要加一个数据库限制(外键约束)constrained="true"
-->
<one-to-one name="idCard" constrained="true"/>
</class>
</hibernate-mapping>
导出至数据库表生成代码如下:
|
create table t_idcard (id integer not null auto_increment, cardNo varchar(255), primary key (id)) create table t_person (id integer not null, name varchar(255), primary key (id)) alter table t_person add index FK785BED805248EF3 (id), add constraint FK785BED805248EF3 foreign key (id) references t_idcard (id) * alter table …… 意思:person的主键id以外键参照idcard的主键 |
※<one-to-one>标签※
现在是使用一对一主键关联映射,因为主键不是自己生成的,而是作为一个外键(来源于其它值),所以使用foreign生成策略(使用另外一个相关联的对象的标识符,通常和<one-to-one>联合起来使用)。再使用元素<param>的属性值指定相关联对象(这里Person相关联的对象为idCard,则标识符为idCard的id)为了能够在加载person数据同时加载IdCard数据,所以需要使用一个标签<one-to-one>来设置这个功能。
<id name="id" column="id">
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
<one-to-one name="idCard" constrained="true"/>
一对一 主键关联映射 存储测试
session = HibernateUtils.getSession();
tx = session.beginTransaction();
IdCard idCard = new IdCard();
idCard.setCardNo("88888888888888888888888");
Person person = new Person();
person.setName("菜10");
person.setIdCard(idCard);
//不会出现TransientObjectException异常
//因为一对一主键关键映射中,默认了cascade属性。
session.save(person);
tx.commit();
注:不会出现TransientObjectException异常,因为一对一主键关键映射中,默认了cascade属性。
生成SQL语句:
|
Hibernate: insert into t_idcard (cardNo) values (?) Hibernate: insert into t_person (name, id) values (?, ?) |
一对一 主键关联映射 加载测试
session = HibernateUtils.getSession();
tx = session.beginTransaction();
Person person = (Person)session.load(Person.class, 1);
System.out.println("person.name=" + person.getName());
System.out.println("idCard.cardNo=" + person.getIdCard().getCardNo());
// 提交事务
tx.commit();
生成SQL语句:
|
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from t_person person0_ where person0_.id=? person.name=菜10 Hibernate: select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idcard idcard0_ where idcard0_.id=? idCard.cardNo=88888888888888888888888 |
一对一 主键关联映射 总结:
让两个实体对象的ID保持相同,这样可以避免多余的字段被创建
<id name="id" column="id">
<!—person的主键来源idcard,也就是共享idCard的主键-->
<generator class="foreign">
<param name="property">idCard</param>
</generator>
</id>
<property name="name"/>
<!—one-to-one标签的含义:指示hibernate怎么加载它的关联对象,默认根据主键加载
constrained="true",表面当前主键上存在一个约束:person的主键作为外键参照了idCard-->
<one-to-one name="idCard" constrained="true"/>
009一对一 主键关联映射_单向(one-to-one)的更多相关文章
- 010一对一 主键关联映射_双向(one-to-one)
² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库 ...
- 011一对一 唯一外键关联映射_单向(one-to-one)
² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库 ...
- Hibernate,关系映射的多对一单向关联、多对一双向关联、一对一主键关联、一对一外键关联、多对多关系关联
2018-11-10 22:27:02开始写 下图内容ORM.Hibernate介绍.hibername.cfg.xml结构: 下图内容hibernate映射文件结构介绍 下图内容hibernate ...
- Hibernate关联映射1:一对一主键关联
2张表之间通过主键形成一对一映射关系,如一个人只能有一张身份证: t_identity_card表建表语句: CREATE TABLE `t_identity_card` ( `id` int(11) ...
- Hibernate5.2之一对一主键关联(四)
Hibernate5.2之一对一主键关联(四) 一.简介 一对一关联关系分为两种:a.主键关联:b. ...
- 012一对一 唯一外键关联映射_双向(one-to-one)
² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库 ...
- Hibernate注解:一对一主键关联
情形:两个表,my_site和my_site_company,通过主键site_id唯一关联.my_site的主键是自动增加,my_site_company的主键依赖于my_site. # # Sou ...
- java:Hibernate框架2(关联映射(多对一,一对多,一对多双向,一对一主键,一对一唯一外键,多对多双向))
hibernate.cfg.xml: <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE h ...
- hibernate一对一主键双向关联
关联是类(类的实例)之间的关系,表示有意义和值得关注的连接. 本系列将介绍Hibernate中主要的几种关联映射 Hibernate一对一主键单向关联Hibernate一对一主键双向关联Hiberna ...
随机推荐
- FunDA:一个开源的函数式数据处理工具库,也是Slick的补充
如果你是一个Slick用户,或者你是一个数据库编程人员正在尝试进入函数式编程模式,那么FunDA可能会帮到你. 目前市面上FRM(Functional Relational Mapper),即函数式的 ...
- 文件系统与linux相关知识点
文件系统是操作系统中管理持久性数据的子系统,提供数据存储和访问功能.对于服务器开发人员,比较关注的是unix(linux)环境下的文件系统,比如分区与磁盘关系,磁盘的剩余空间,文件的类型与权限控制,文 ...
- C#, VB.NET如何将Excel转换为PDF
在日常工作中,我们经常需要把Excel文档转换为PDF文档.你是否在苦恼如何以C#, VB.NET编程的方式将Excel文档转换为PDF文档呢?你是否查阅了许多资料,运用了大量的代码,但转换后的效果依 ...
- Anaconda配置多spyder多python环境
作者:桂. 时间:2017-04-17 22:02:37 链接:http://www.cnblogs.com/xingshansi/p/6725298.html 前言 最近在看<统计学习方法 ...
- 笔记:查看linux系统开机时间
[root@localhost ~]# uptime -s -- :: 通过命令uptime -s 查看系统开机时间
- lua 运算符
lua 运算符 算术运算符 操作符 描述 + 加 - 减 * 乘 / 除 % 求模 ^ 求幂 示例程序 local a, b = 1, 2 print(a + b) print(a - b) prin ...
- 从花式swap引出的pointer aliasing问题
上次,一个同学问我,你知不知道可以不用引入中间变量就可以实现swap? 我说,我知道,可以用加减法或者异或实现,像是这样 void mySwap(int &x,int &y) { x= ...
- Google Earth影像数据破解之旅
"Zed, you are so excellent." 为什么要写这句英文?容我卖个关子稍后再解释. 相信大多数人都体验过Google Earth(简称GE),我对GE最初的印象 ...
- PMBOK 学习与实践分享视频
本系列为自己在学习PMBOK时进行的总结与分享,每一节主要包括两部分: 对PMBOK本身的一个结构笔记和讲解. 对自己项目管理工作的一个总结和思考. PMBOK 学习与实践分享视频内容清单 人力资源管 ...
- 好看的复选框(Checkbox)效果
在线演示 源码下载