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. BZOJ_4326_[NOIP2015]_运输计划_(二分+LCA_树链剖分/Tarjan+差分)

    描述 http://www.lydsy.com/JudgeOnline/problem.php?id=4326 给出一棵带有边权的树,以及一系列任务,任务是从树上的u点走到v点,代价为u到v路径上的权 ...

  2. 【转】国内用户如何加快App Store的访问速度

    原文网址:http://www.app111.com/doc/100024206_1.html 作为国内互联网用户是比较可怜的,除了国外四大顶尖互联网服务不能访问外,就是App Store用得也比较痛 ...

  3. servlet读取cookie问题

    String sessionid = request.getSession().getId(); // 取得当前的session id ckSessionid = new Cookie("s ...

  4. 基于WebForm+EasyUI的业务管理系统形成之旅 -- 总体介绍

    一.系统总体介绍 企业业务管理系统是针对经营企业管理而开发的专业管理软件, 是以“精细管理.过程监控”为设计理念,全面满足企业的信息化管理需求,充分发挥专业.平台.灵活等优点. 集进销存.财务.CRM ...

  5. Android图片上传,可以选择多张图片,缩放预览,拍照上传等

    仿照微信,朋友圈分享图片功能 .可以进行图片的多张选择,拍照添加图片,以及进行图片的预览,预览时可以进行缩放,并且可以删除选中状态的图片 .很不错的源码,大家有需要可以下载看看 . 微信 微信 微信 ...

  6. mysql 查看死锁和去除死锁

    1.查询是否锁表show OPEN TABLES where In_use > 0; 2.查询进程 show processlist 3.  查询到相对应的进程,然后 kill id 验证(ki ...

  7. 多控制器之UIWindow

    *:first-child { margin-top: 0 !important; } body > *:last-child { margin-bottom: 0 !important; } ...

  8. Linux内核系列设备模型(一) Kobject与Kset

    1.Kobject Kobject是设备驱动模型的核心结构,它使所有设备在底层都有统一的接口.在内核注册的kobject对象都会对应sysfs文件系统中的一个目录(目录名称有Kobject结构中k_n ...

  9. 使用 IntelliJ IDEA 导入 Spark 最新源码及编译 Spark 源代码

    前言   其实啊,无论你是初学者还是具备了有一定spark编程经验,都需要对spark源码足够重视起来. 本人,肺腑之己见,想要成为大数据的大牛和顶尖专家,多结合源码和操练编程. 准备工作 1.sca ...

  10. Redis和Memcache的对比

    我这段时间在用redis,感觉挺方便的,但比较疑惑在选择内存数据库的时候到底什么时候选择redis,什么时候选择memcache,然后就查到下面对应的资料,是来自redis作者的说法(stackove ...