文档章节

hibernate系列(四)一对一关联关系

乒乓狂魔
 乒乓狂魔
发布于 2015/02/07 10:24
字数 1032
阅读 65
收藏 1
点赞 0
评论 0
以Person类和IDCard类为例,这里仅仅说一种一对一关联关系,即Person类拥有IDCard,但是IDCard不含Person类,数据库库的表如下:
CREATE TABLE `hibernate`.`person` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `name` VARCHAR(45) NULL,
  `age` INT NULL,
  `idcard_id` INT NULL,
  PRIMARY KEY (`id`));

CREATE TABLE `hibernate`.`idcard` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `number` INT NULL,
  `content` VARCHAR(45) NULL,
  PRIMARY KEY (`id`));

Person类如下:
public class Person {

	private Long id;
	private String name;
	private Long age;
	private IDCard idCard;
//省略get、set方法
}

Person类对应的Person.hbm.xml映射文件为:
<hibernate-mapping>
	<class name="com.ligang.domain.Person" table="person">
		<id name="id" column="id" type="long">
			<generator class="identity"/>
		</id>
		<property name="name" column="name" type="string"/>
		<property name="age" column="age" type="long"/>
		<many-to-one name="idCard" class="com.ligang.domain.IDCard" column="idcard_id" cascade="save-update"></many-to-one>
	</class>
</hibernate-mapping>

虽然是一对一但是,这种形式的一对一就是多对一的特例,所以仍然使用<many-to-one>的标签,其中的name指的是Person类的idCard属性,column指的是person表中的字段名为idcard_id,class指的是将IDCard类对应的表的主键的值作为idcard_id的值。cascade字段表示保存Person类时级联的保存IDCard类。
下面看下IDCard类:

public class IDCard {

	private Long id;
	private Long number;
	private String content;
//省略get、set方法
}

IDCard类对应的IDCard.hbm.xml映射文件为:
<hibernate-mapping>
	<class name="com.ligang.domain.IDCard" table="idcard">
		<id name="id" column="id" type="long">
			<generator class="identity"/>
		</id>
		<property name="number" column="number" type="long"/>
		<property name="content" column="content" type="string"/>
	</class>
</hibernate-mapping>

然后就是测试增添方法:
@Test
	public void addPerson(){
		Session session=hibernateDao.getSession();
		Transaction tx=session.beginTransaction();
		
		Person p=new Person();
		p.setName("张三");
		p.setAge(122L);
		
		IDCard idCard=new IDCard();
		idCard.setNumber(123445L);
		idCard.setContent("你是一个人");
		
		p.setIdCard(idCard);
		
		session.save(p);
		
		tx.commit();
		session.close();
	}

此时就会先保存IDCard对象,然后获取其主键并赋值给person表的idcard_id字段,然后增添Person对象。如下sql:
Hibernate: insert into hibernate.idcard (number, content) values (?, ?)
Hibernate: insert into hibernate.person (name, age, idcard_id) values (?, ?, ?)

更新如下:
@Test
	public void updatePerson(){
		Session session=hibernateDao.getSession();
		Transaction tx=session.beginTransaction();
		
		Person p=(Person) session.get(Person.class,6L);
		p.setName("张三");
		p.setAge(122L);
		
		IDCard idCard=new IDCard();
		idCard.setNumber(123445L);
		idCard.setContent("你是一个人");
		
		p.setIdCard(idCard);
		
		session.save(p);
		
		tx.commit();
		session.close();
	}

此时的sql如下:
Hibernate: select person0_.id as id1_3_0_, person0_.name as name2_3_0_, person0_.age as age3_3_0_, person0_.idcard_id as idcard_i4_3_0_ from hibernate.person person0_ where person0_.id=?
Hibernate: insert into hibernate.idcard (number, content) values (?, ?)
Hibernate: update hibernate.person set name=?, age=?, idcard_id=? where id=?

此时并没有删除原有的IDCard,只是根据Person再也找不到它了。目前我还不知道怎么设置来删除无用的IDCard。

获取:由Person的主键获取IDCard比较容易,但是如果想从IDCard主键获取Person呢?
首先更改IDCard类,添加person属性:

public class IDCard {

	private Long id;
	private Long number;
	private String content;
	private Person person;
//略get、set方法
}

然后更改上述的IDCard.hbm.xml映射文件如下:
<hibernate-mapping>
	<class name="com.ligang.domain.IDCard" table="idcard">
		<id name="id" column="id" type="long">
			<generator class="identity"/>
		</id>
		<property name="number" column="number" type="long"/>
		<property name="content" column="content" type="string"/>
		<one-to-one name="person" property-ref="idCard"></one-to-one>
	</class>
</hibernate-mapping>

添加了<one-to-one>标签,同时使用了property-ref属性,看下查询再解释:
@Test
	public void getPerson(){
		Session session=hibernateDao.getSession();
		Transaction tx=session.beginTransaction();
		
		IDCard idCard=(IDCard) session.get(IDCard.class,2L);
		System.out.println(idCard.getPerson().getName());
		
		tx.commit();
		session.close();
	}

查询的sql如下:
Hibernate: select idcard0_.id as id1_1_0_, idcard0_.number as number2_1_0_, idcard0_.content as content3_1_0_, person1_.id as id1_3_1_, person1_.name as name2_3_1_, person1_.age as age3_3_1_, person1_.idcard_id as idcard_i4_3_1_ from hibernate.idcard idcard0_ left outer join hibernate.person person1_ on idcard0_.id=person1_.idcard_id where idcard0_.id=?
张三

将Person查出来了,然后看下他是怎么查的,看下IDCard的<one-to-one name="person" property-ref="idCard">,name指的是IDCard的person属性,而property-ref指向了另一个类的属性,这里就是Person类的idCard属性,要想查出Person总要告诉hibernate idcard表的哪个字段和person表的哪个字段相连接吧,这里的property-ref="idCard",即指定了要和Person类的idCard属性所对应的字段相连接,默认是采用主键来和该字段相连接的,我不知道能否指定。即idcard表的主键id和Person类的idCard属性对应的字段idcard_id相连接,来查询Person,看sql语句:hibernate.idcard idcard0_ left outer join hibernate.person person1_ on idcard0_.id=person1_.idcard_id

上述一对一的关联关系是通过外键来连接,他们也可以使用相同的主键实现一对一。这里不再讲述。

若想转载请注明出处
作者:乒乓狂魔

© 著作权归作者所有

共有 人打赏支持
乒乓狂魔
粉丝 979
博文 105
码字总数 271356
作品 0
长宁
程序员
Hibernate系列——总结篇(九)

概念 Hibernate是一个对象关系映射框架,当然从分层的角度看,我们也说它是数据持久层的框架。 我们从上一句话可以看出Hibernate的核心:面向对象、关系映射以及数据持久化。前面两个概念很容...

architect刘源源
01/11
5
0
Hibernate Hibernate关联映射

Hibernate映射关系概述: Hibernate关联映射分为: ①、多对一。②、一对多。③、一对一。④、多对多。⑤、组件映射。⑥、集合映射。 在Uml语言中关联是有方向的,以客户Customer和订单Order...

Winnie007
2015/08/06
0
0
Hibernate(三)——框架中的关系映射

在设计数据库时我们会考虑,表与表之间的关系,例如我们前边经常提到的一对一,一对多,多对多关系,在数据库中我们通过外键,第三张表等来实现这些关系。而Hibernate时间实体类和数据库中的...

凡尘里的一根葱
2015/11/11
0
0
Hibernate映射——一对一双向关联映射(六)

我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息。如图所示: 关键原因在于对象模型具有方向性: 单向:一...

architect刘源源
01/11
3
0
Hibernate框架学习之注解配置关系映射

上篇文章我们通过注解对映射了单个实体类,但是具体项目中往往实体类之间又是相互关联的,本篇文章就是从实体类之间存在的不同关联角度,具体学习下如何映射他们之间的关联,主要涉及内容如下...

Single_YAM
2017/11/15
0
0
Hibernate映射——一对一单向关联映射(五)

映射原理 两个实体对象之间是一对一的关联映射,即一个对象只能与另外唯一的一个对象相对应。例如:一个人(Person)只有一张身份证(IdCard)。我们看一下这个例子的对象模型,如下图所示: 对象...

architect刘源源
01/11
2
0
day30_Hibernate学习笔记_02

一、Hibernate中对象的状态 对象状态   瞬时态|临时态:Transient     1、没有与Hibernate产生关联(没有与Session有关联)。     2、与数据库中的记录没有产生关联,即对象没有ID(...

黑泽明军
07/11
0
0
Hibernate之关联关系映射(一对一主键映射和一对一外键映射)

1:Hibernate的关联关系映射的一对一外键映射:   1.1:第一首先引包,省略   1.2:第二创建实体类:     这里使用用户信息和身份证信息的关系,用户的主键编号既可以做身份证信息的...

别叫小伙
2017/03/22
0
0
Java程序员从笨鸟到菜鸟之(五十八)细谈Hibernate(九)hibernate一对一关系映射

一对一关系映射即为关系双方都含有对方一个引用,其实在生活中一对一关系也很常见,比如人和身份证,学生和学号等,都是一对一的关系映射,一对一映射分为单向的和双向的,没种关系映射又可以...

长平狐
2012/11/12
84
0
【持久化框架】Mybatis与Hibernate的详细对比

前言 这篇博文我们重点分析一下Mybatis与Hibernate的区别,当然在前面的博文中我们已经深入的研究了Mybatis和Hibernate的原理。 Mybatis 【持久化框架】Mybatis简介与原理 【持久化框架】Spr...

sietai
05/18
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

JPA @MappedSuperclass 注解说明

基于代码复用和模型分离的思想,在项目开发中使用JPA的@MappedSuperclass注解将实体类的多个属性分别封装到不同的非实体类中。 1.@MappedSuperclass注解只能标准在类上:@Target({java.lang....

海博1600
15分钟前
0
0
Scala Configuration 相关API

Play使用了 Typesafe config library,但是也提供了一个有着更多Scala高级特性的的 Configuration 封装。不熟悉Typesafe配置的开发者可以移步 configuration文件的语法和特性文档。 读取配置...

Landas
今天
1
0
使用cookie技术 记住账号

1. 效果 2. 实现过程 2.1 前端 将用户的选中传递给后台 这个参数的获取是 参考:https://my.oschina.net/springMVCAndspring/blog/1860498 // var rememberLogin = $("#rememberLoginId").i...

Lucky_Me
今天
1
0
《趣谈网络协议》02之网络分层的真实含义

一、提出问题 1.提出问题 当你听到什么二层设备、三层设备、四层 LB 和七层 LB 中层的时候,是否有点一头雾水,不知道这些所谓的层,对应的各种协议具体要做什么“工作”? 2.这四个问题你弄...

aibinxiao
今天
2
0
Python3学习日志二 Python中的集合set和字典dict

1.集合set 定义一个集合set 我们可以看到定义集合set有两种不同的形式,如果要定义一个空的集合set不能用{}而是要用set();另外,集合是无序的,而且set中的元素是不可重复的,如果你定义了一...

Mr_bullshit
今天
0
0
adb 操作指令详解

ADB,即 Android Debug Bridge,它是 Android 开发/测试人员不可替代的强大工具,也是 Android 设备玩家的好玩具。 注:有部分命令的支持情况可能与 Android 系统版本及定制 ROM 的实现有关。...

孟飞阳
今天
0
0
nodejs安装以及环境配置(很好的node安装和配置文章,少走很多弯路)

一、安装环境 1、本机系统:Windows 10 Pro(64位) 2、Node.js:v6.9.2LTS(64位) 二、安装Node.js步骤 1、下载对应你系统的Node.js版本:https://nodejs.org/en/download/ 2、选安装目录进...

sprouting
今天
1
0
Redisson

了解了Redisson,发现使用挺简单的,接下来准备深入学习一下。 Redisson介绍 Redisson是架设于Redis基础之上的一个Java驻内存数据网格(In-Memory Data Grid) Redisson在基于NIO的Netty框架上...

to_ln
今天
0
0
python有哪些好玩的应用实现,用python爬虫做一个二维码生成器

python爬虫不止可以批量下载数据,还可以有很多有趣的应用,之前也发过很多,比如天气预报实时查询、cmd版的实时翻译、快速浏览论坛热门帖等等,这些都可以算是爬虫的另一个应用方向! 今天给...

python玩家
今天
0
0
python爬虫日志(3)-爬去异步加载网页

在浏览器检查元素页面中,选取Network中的XHR选项即可观察每次加载页面,网页发出的请求,观察url的规律即可利用封装的函数对每一页进行爬取。

茫羽行
今天
0
0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部