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 ...
随机推荐
- NOI2010海拔
2007: [Noi2010]海拔 Time Limit: 20 Sec Memory Limit: 552 MBSubmit: 1302 Solved: 612[Submit][Status] ...
- BrnShop开源网上商城第一讲:架构设计
首先在此感谢大家对BrnShop项目的支持和鼓励!我们在发布BrnShop以前曾推测项目会受到不少园友的支持,但没想到园友们的支持大大超过我们的预测.4天6000次浏览,140个推荐,170个评论,8 ...
- WinForm触摸屏程序功能界面长时间不操作自动关闭回到主界面 z
操作者经常会在执行了某操作后,没有返还主界面就结束了操作然后离开了,程序应该关闭功能窗体自动回到主界面方便下一位操作者操作.那么对于WinForm程序怎么实现呢? 实现原理:拦截Application ...
- Prism的IEventAggregator事件聚合器, 事件订阅发布, ViewModel之间的通讯
WPF中时常会遇到ViewModel之间的通讯,ViewModel并不知道自己的View,但是一个View发生的更改需要通知另外一个View. 举一个例子,软件界面上有个人信息,打开一个界面更改用户的 ...
- 曲面Shader
这是一个能让平面呈现出曲面效果的Shaer. 代码: Shader "Custom/CurvedWorld"{ Properties { // Diffuse texture _M ...
- SSAS使用MDX生成脱机的多维数据集CUB文件
在运用多维数据进行分析的时候,通常很有可能我们需要把这些多维数据脱机进行处理或演示,这其中就要用到cub文件 http://www.cnblogs.com/yunhuasheng/archive/20 ...
- Android完全退出应用程序,完美解决方案
最近公司工作不是很忙,就抽空研究了下Android的引导页,但是在写完引导页并且进入到住页面之后,在退出时,采用"再按一次退出"的方式去实现的,用的方式是杀掉进程跟exit,即:a ...
- leetcode@ [51/52] N-Queens
https://leetcode.com/problems/n-queens/ class Solution { public: void dfs(vector<vector<string ...
- POJ1050:To the max
poj1050:http://poj.org/problem?id=1050 * maximum-subarray 问题的升级版本~ 本题同样是采用DP思想来做,同时有个小技巧处理:就是把二维数组看做 ...
- windows下利用dll生成lib
原来工程编译的一些dll库,这次项目需要静态库,偷懒想直接转化.看到网上一些教程,使用VC工具和建立lib项目来实现.有点麻烦.还有一种方法,仅仅利用工具和几条命令转化.来试试看.文章参考harrie ...