2张表之间通过主键形成一对一映射关系,如一个人只能有一张身份证:

t_identity_card表建表语句:

CREATE TABLE `t_identity_card` (
`id` int(11) NOT NULL,
`identity` int(11) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;

t_person表建表语句:

CREATE TABLE `t_person` (
`id` int(11) NOT NULL,
`name` varchar(255) NOT NULL,
`age` int(11) NOT NULL,
PRIMARY KEY (`id`),
CONSTRAINT `FK_ID` FOREIGN KEY (`id`) REFERENCES `t_identity_card` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312;

hibernate.cfg.xml:

<?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="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/mydb</property>
<property name="connection.username">root</property>
<property name="connection.password">196428</property> <property name="hibernate.show_sql">true</property> <mapping resource="com/po/IdentityCard.hbm.xml" />
<mapping resource="com/po/Person.hbm.xml" />
</session-factory>
</hibernate-configuration>

单向一对一主键关联:

t_identity_card表:

public class IdentityCard implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private int identity;
private Person person; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getIdentity() {
return identity;
}
public void setIdentity(int identity) {
this.identity = identity;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}

由于t_identity_card表使用foreign主键生成策略,故在t_identity_card表的配置文件中必须配置主键生成表t_person,这样在向t_identity_card表中插入数据时才能找到所需的主键值,所以单向一对一主键关联中只有t_person<-t_identity_card,没有t_person->t_identity_card

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.po.IdentityCard" table="t_identity_card">
<id name="id" column="id" type="integer">
<generator class="foreign">
<param name="property">person</param>
</generator>
</id>
<property name="identity" column="identity" type="integer"/>
<one-to-one name="person" class="com.po.Person"/>
</class>
</hibernate-mapping>

t_person表:

public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private int age; 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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.po.Person" table="t_person">
<id name="id" column="id" type="integer">
<generator class="assigned"/>
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="integer"/>
</class>
</hibernate-mapping>

测试一下:

public class Test {
public static void main(String[] args) {
Configuration conf = new Configuration();
SessionFactory sessionFactory = conf.configure().buildSessionFactory();
Session session = sessionFactory.openSession(); IdentityCard identityCard = new IdentityCard();
identityCard.setIdentity(123456);
Person person = new Person();
person.setId(1);
person.setName("sean");
person.setAge(25);
identityCard.setPerson(person); Transaction tran = session.beginTransaction();
session.save(identityCard);
tran.commit(); IdentityCard identityCard2 = (IdentityCard)session.get(IdentityCard.class, 1);
Person person2 = identityCard2.getPerson();
System.out.println(person2.getName()); session.close();
}
}

测试结果为:

Hibernate: insert into t_identity_card (identity, id) values (?, ?)
sean

只向t_identity_card表中插入了数据,t_person表为空,由于没有设置关联关系的cascade属性,在持久化一张表的时候,并不会级联的持久化另一张表

将t_identity_card表的映射文件中的关联关系修改为:<one-to-one name="person" class="com.po.Person"cascade="all" />

Hibernate: select person_.id, person_.name as name1_, person_.age as age1_
from t_person person_ where person_.id=?
Hibernate: insert into t_identity_card (identity, id) values (?, ?)
Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
sean

双向一对一主键关联:

这时需要对t_person表的配置做一些修改:

public class Person implements Serializable {
private static final long serialVersionUID = 1L;
private int id;
private String name;
private int age;
private IdentityCard identityCard;//新增 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 int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public IdentityCard getIdentityCard() {
return identityCard;
}
public void setIdentityCard(IdentityCard identityCard) {
this.identityCard = identityCard;
}
}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd" >
<hibernate-mapping>
<class name="com.po.Person" table="t_person">
<id name="id" column="id" type="integer">
<generator class="native"/>
</id>
<property name="name" column="name" type="string"/>
<property name="age" column="age" type="integer"/>
<!--新增-->
<one-to-one name="identityCard" class="com.po.IdentityCard" cascade="all" />
</class>
</hibernate-mapping>

测试一下:

public class Test {
public static void main(String[] args) {
Configuration conf = new Configuration();
SessionFactory sessionFactory = conf.configure().buildSessionFactory();
Session session = sessionFactory.openSession(); IdentityCard identityCard = new IdentityCard();
identityCard.setIdentity(123456);
Person person = new Person();
person.setId(1);
person.setName("sean");
person.setAge(25); identityCard.setPerson(person);
person.setIdentityCard(identityCard); Transaction tran = session.beginTransaction();
session.save(identityCard);
tran.commit(); Person person_tmp = (Person)session.get(Person.class, 1);
IdentityCard id_card_tmp = person_tmp.getIdentityCard();
System.out.println(id_card_tmp.getIdentity()); id_card_tmp = (IdentityCard)session.get(IdentityCard.class, 1);
person_tmp = id_card_tmp.getPerson();
System.out.println(person_tmp.getName()); session.close();
}
}

测试结果为:

Hibernate: select person_.id, person_.name as name1_, person_.age
as age1_ from t_person person_ where person_.id=?
Hibernate: insert into t_identity_card (identity, id) values (?, ?)
Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
123456
sean

Hibernate首先持久化了identityCard对象,将测试代码中的session.save(identityCard)修改为session.save(person),再次测试:

Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
Exception in thread "main" org.hibernate.exception.ConstraintViolationException:
Could not execute JDBC batch update
......
Caused by: java.sql.BatchUpdateException: Cannot add or update a child row:
a foreign key constraint fails (`mydb`.`t_person`, CONSTRAINT `FK_ID`
FOREIGN KEY (`id`) REFERENCES `t_identity_card` (`id`))
......

Hibernate这次首先持久化了person对象,由于t_person表中的id字段建立了外键关系,故持久化失败,删除掉t_person表中id字段的外键关系之后,插入正常:

Hibernate: insert into t_person (name, age, id) values (?, ?, ?)
Hibernate: insert into t_identity_card (identity, id) values (?, ?)
123456
sean

可见Hibernate有时不是很智能,save的对象将会首先被持久化,这时要特别注意表上建立的关联关系

Hibernate关联映射1:一对一主键关联的更多相关文章

  1. Hibernate,关系映射的多对一单向关联、多对一双向关联、一对一主键关联、一对一外键关联、多对多关系关联

    2018-11-10  22:27:02开始写 下图内容ORM.Hibernate介绍.hibername.cfg.xml结构: 下图内容hibernate映射文件结构介绍 下图内容hibernate ...

  2. 010一对一 主键关联映射_双向(one-to-one)

    ²  两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ²  有两种策略可以实现一对一的关联映射 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库 ...

  3. 009一对一 主键关联映射_单向(one-to-one)

    009一对一  主键关联映射_单向(one-to-one) ²  两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ²  有两种策略可以实现一对一的关联映射 主键关联:即让两个 ...

  4. Hibernate5.2之一对一主键关联(四)

                                                      Hibernate5.2之一对一主键关联(四) 一.简介 一对一关联关系分为两种:a.主键关联:b. ...

  5. Hibernate注解:一对一主键关联

    情形:两个表,my_site和my_site_company,通过主键site_id唯一关联.my_site的主键是自动增加,my_site_company的主键依赖于my_site. # # Sou ...

  6. hibernate5(12)注解映射[4]一对一外键关联

    在实际博客站点中,文章内容的数据量非常多,它会影响我们检索文章其他数据的时间,如查询公布时间.标题.类别的等. 这个时候,我们能够尝试将文章内容存在还有一张表中,然后建立起文章--文章内容的一对一映射 ...

  7. hibernate 关系映射之 双向外键关联一对一

    在上一篇博客内容的基础上做了以下修改,即可实现.   注解方式:   package com.bjsxt.hibernate; import javax.persistence.Entity; imp ...

  8. hibernate 关系映射之 单向外键关联一对一

    这里的关系指的是对象与对象之间的关系 注解方式单向关联一对一: //这个类描述的husband是一个对应一个wife的 import javax.persistence.Entity; import ...

  9. Hibrenate关系映射(一对一外键关联)

    一.一对一(单向):使用外部索引将其中的一个类作为parent,相对应的一个就是子类,并且参照父 类的主键ID来生成数据库表.(比如:可以将husband中设置一个wife_id对应wife中的主键i ...

随机推荐

  1. usaco4.12Fence Rails(迭代加深)

    为了这题还去学了下迭代加深 回来还是不会写 只好参考各大神的代码及题解了 二分枚举最大可以切的块数 然后就是各种分析及优化 USACO题解里写了7个优化.. 问题分析 抽象一下就可以发现,算法的本质是 ...

  2. bzoj1670

    第一道凸包 采用Andrew算法,不论实现还是理解都非常简单 ..] of longint;     i,j,k,m,n:longint;     ans:double; procedure swap ...

  3. [swustoj 764] 校门外的树 Plus Plus

    校门外的树 Plus Plus(0764) 问题描述 西南某科技大学的校门外长度为 L 的公路上有一排树,每两棵相邻的树之间的间隔都是 1 米.我们可以把马路看成一个数轴,马路的一端在数轴 1 的位置 ...

  4. 谈谈分布式事务之三: System.Transactions事务详解[上篇]

    在.NET 1.x中,我们基本是通过ADO.NET实现对不同数据库访问的事务..NET 2.0为了带来了全新的事务编程模式,由于所有事务组件或者类型均定义在System.Transactions程序集 ...

  5. LightOJ 1356 Prime Independence 二分图最大独立集,HK算法

    这个题唯一需要说的就是普通的匈牙利算法是O(nm)的,过不了 然后HK算法可以O(n^0.5m),这个算法可以每次找很多同样长度的最短增广路 分析见:http://www.hardbird.net/l ...

  6. VMware ESXi CentOS Linux虚拟机安装VMware Tools教

    转自VMware ESXi CentOS Linux虚拟机安装VMware Tools教程 | 一米居 http://www.yimiju.com/articles/548.html 最近一周在学习和 ...

  7. 启动Selenium RC —— 我的第一个shell

    打开终端 1. 新建一个sh文件 $ vim a.sh 2. 写入以下内容 #! /bin/bash cd Desktop/selenium/jar java -jar selenium-server ...

  8. HDU-4415 Assassin’s Creed 贪心

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4415 用贪心来解,开始分为两个集合的方法错了,没有考虑之间的相互影响,正确的姿势应该是这样的,分两种情 ...

  9. Codeforces Round #226 (Div. 2)B. Bear and Strings

    /* 题意就是要找到包含“bear”的子串,计算出个数,需要注意的地方就是不要计算重复. */ 1 #include <stdio.h> #include <string.h> ...

  10. 【转】sublime text 2 下的Markdown写作

    sublime text 2 下的Markdown写作   作为Windows/Mac/Linux下强大的文本编辑器,st提供了对Markdown语言的支持.通过设置可实现markdown预览和转换功 ...