Hibernate关联映射1:一对一主键关联
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:一对一主键关联的更多相关文章
- Hibernate,关系映射的多对一单向关联、多对一双向关联、一对一主键关联、一对一外键关联、多对多关系关联
2018-11-10 22:27:02开始写 下图内容ORM.Hibernate介绍.hibername.cfg.xml结构: 下图内容hibernate映射文件结构介绍 下图内容hibernate ...
- 010一对一 主键关联映射_双向(one-to-one)
² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系:数据库 ...
- 009一对一 主键关联映射_单向(one-to-one)
009一对一 主键关联映射_单向(one-to-one) ² 两个对象之间是一对一的关系,如Person-IdCard(人—身份证号) ² 有两种策略可以实现一对一的关联映射 主键关联:即让两个 ...
- Hibernate5.2之一对一主键关联(四)
Hibernate5.2之一对一主键关联(四) 一.简介 一对一关联关系分为两种:a.主键关联:b. ...
- Hibernate注解:一对一主键关联
情形:两个表,my_site和my_site_company,通过主键site_id唯一关联.my_site的主键是自动增加,my_site_company的主键依赖于my_site. # # Sou ...
- hibernate5(12)注解映射[4]一对一外键关联
在实际博客站点中,文章内容的数据量非常多,它会影响我们检索文章其他数据的时间,如查询公布时间.标题.类别的等. 这个时候,我们能够尝试将文章内容存在还有一张表中,然后建立起文章--文章内容的一对一映射 ...
- hibernate 关系映射之 双向外键关联一对一
在上一篇博客内容的基础上做了以下修改,即可实现. 注解方式: package com.bjsxt.hibernate; import javax.persistence.Entity; imp ...
- hibernate 关系映射之 单向外键关联一对一
这里的关系指的是对象与对象之间的关系 注解方式单向关联一对一: //这个类描述的husband是一个对应一个wife的 import javax.persistence.Entity; import ...
- Hibrenate关系映射(一对一外键关联)
一.一对一(单向):使用外部索引将其中的一个类作为parent,相对应的一个就是子类,并且参照父 类的主键ID来生成数据库表.(比如:可以将husband中设置一个wife_id对应wife中的主键i ...
随机推荐
- BZOJ_1623:_[Usaco2008_Open]_Cow_Cars_奶牛飞车_(贪心)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1623 n头牛,第i头牛的速度是si,m条路(m<=n).如果第i头牛前面有k头牛,它的速 ...
- Chrome的隐身模式
先来说说隐身模式的启用方法吧 1.键盘快捷:Ctrl + Shift + N. 2.在Windows7下的任务栏处,右击“Chrome”图标,会出一个下拉菜单,点击“新建隐身窗口”. 3.你还可以在一 ...
- C# 线程知识--使用ThreadPool执行异步操作
C# 线程知识--使用ThreadPool执行异步操作 在应用程序中有许多复杂的任务,对于这些任务可能需要使用一个或多个工作线程或I/O线程来协作处理,比如:定时任务.数据库数据操作.web服务.文件 ...
- java.lang.IllegalStateException: Required view 'text1' with ID 2131492943 for field 'mText' was not found. If this view is optional add '@Nullable' annotation
使用ButterKnife 8.2的时候遇到这个问题 很明显空指针问题 按照提示添加 import android.support.annotation.Nullable;@Nullable 造成原 ...
- Microsoft StreamInsight install
Microsoft StreamInsight 是一个开发平台.安装之后,可通过一组 .NET 命名空间来得到 SDK.有关 StreamInsight 应用程序开发的其他信息,请参阅上面列出的资源. ...
- IIS中访问自己开发的Webservice site就自动停止,尝试重启IIS和重启服务器都不能解决。
今天在加班的时候发现一个奇怪的问题,IIS里面我们自己开发的Webservice site一访问就自动停止.尝试重启IIS和重启服务器都不能解决.后台windows events报错信息是The Mo ...
- Asp.Net MVC4新特性指南(2):新特性介绍
上一章讲解了最基本的MVC4说明.今天就介绍下几种新特性的使用例子: 就当大家有MVC3的基础了.在这个基础上在看下面的介绍就容易多了.1.Web API MVC4包括一个更好的解决方案:A ...
- vijosP1289 老板娘的促销方案
vijosP1289 老板娘的促销方案 链接:https://vijos.org/p/1289 [思路] 组合公式+高精度. 如果n-m<2则无解. 否则对于第一个询问:ans=C(n-m,2) ...
- HW3.20
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- ffmpeg编解码音频AAC
本次项目的需求:手机端和PC端共享同一个音视频网络源. 所以编解码需要满足手机上编码和解码原来PC端的音视频流. 这里先封装安卓手机端音频的编解码. 编译工作依然是在linux下 ubuntu 12. ...