- 浏览: 1229873 次
- 性别:
- 来自: 深圳
文章分类
- 全部博客 (718)
- HTML (13)
- JS基础 (23)
- JS应用 (40)
- AJAX (6)
- JSP相关 (12)
- JAVA基础 (52)
- JAVA应用 (74)
- APPLET (11)
- SWING\RCP (2)
- JAVA反射 (6)
- 设计模式 (26)
- 数据库设计 (20)
- Struts (35)
- Struts2 (12)
- Spring (22)
- Hibernate (45)
- Ibatis (18)
- mybatis (3)
- SSH (8)
- UML (5)
- WebService (3)
- XML (16)
- Log4j (7)
- WEB容器 (26)
- 数据结构 (36)
- Linux (34)
- Ruby on Rails (1)
- 其它技术 (27)
- IDE配置 (15)
- 项目实战 (2)
- Oracle (69)
- JAVA报表 (7)
- Android学习 (2)
- 博客链接 (1)
- 网络基础 (1)
- WEB集群 (1)
- .Net开发 (11)
- PB (4)
- 系统构建 (15)
最新评论
-
jnjeC:
牛逼啊哥们,讲得太好了
Maven仓库理解、如何引入本地包、Maven多种方式打可执行jar包 -
九尾狐的yi巴:
很好 感谢!
Itext中文处理(更新版) -
luweifeng1983:
有用的,重启一下嘛。
设置eclipse外部修改文件后自动刷新 -
Master-Gao:
设置了也不管用,怎么破呢?
设置eclipse外部修改文件后自动刷新 -
aigo_h:
锋子还有时间写博客,还是很闲哈!
Add directory entries问题
两个表通过主键来关联
就是一个表的主键依赖另一个表的主键,如果一个表里面没有数据,那么在另一关联他的表插入数据会报错。
如下:
配置文件:
<?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 package="com.lwf.hibernate.pojo" > <class name="Person"> <id name="id"> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <property name="name"/> <one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one> </class> <class name="IdCard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> </class> </hibernate-mapping>
POJO
package com.lwf.hibernate.pojo; public class Person { private int id; private String name; private IdCard idCard; public int getId() { return id; } public void setId(int id) { this.id = id; } public IdCard getIdCard() { return idCard; } public void setIdCard(IdCard idCard) { this.idCard = idCard; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
package com.lwf.hibernate.pojo; public class IdCard { private int id; private String cardNo; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getCardNo() { return cardNo; } public void setCardNo(String cardNo) { this.cardNo = cardNo; } }
生成的Sql语句:
create table IdCard ( id integer not null auto_increment, cardNo varchar(255), primary key (id) ) create table Person ( id integer not null, name varchar(255), primary key (id) ) alter table Person add index FK8E488775694BC674 (id), add constraint FK8E488775694BC674 foreign key (id) references IdCard (id)
在数据库中产生两个表:
person表
+-------+--------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id | int(11) | NO | PRI | NULL | |
| name | varchar(255) | YES | | NULL | |
+-------+--------------+------+-----+---------+-------+
idcard表
+--------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| cardNo | varchar(255) | YES | | NULL | |
+--------+--------------+------+-----+---------+----------------+
因为Person的主键关联于idcard的主键,所以必须先在idcard表中插入数据如
insert into idcard(cardNo) values('sfsddf');
产生数据;
+----+--------+
| id | cardNo |
+----+--------+
| 1 | sfsddf |
+----+--------+
下面再执行插入数据到person中。
insert into idcard(cardNo) values('sfsddf');
+----+------+
| id | name |
+----+------+
| 1 | dddl |
+----+------+
如果:
insert into person(id,name) values(3,'dddl');
ERROR 1452 (23000): Cannot add or update a child row: a foreign key constraint f。。
ails (`hibernate`.`person`, CONSTRAINT `FK8E488775694BC674` FOREIGN KEY (`id`) R
EFERENCES `idcard` (`id`))
在使用hibernate进行插入时只需要
public static void main(String[] args) { Session session = openSession(); IdCard idCard = new IdCard(); idCard.setCardNo("1121212"); Person person = new Person(); person.setIdCard(idCard); person.setName("zhangshang"); session.save(person); commitSession(session); closeSession(session); }
生成语句:
Hibernate: /* insert com.lwf.hibernate.pojo.IdCard */ insert into IdCard (cardNo) values (?) Hibernate: /* insert com.lwf.hibernate.pojo.Person */ insert into Person (name, id) values (?, ?)
注意上面我们没有先sesssion.save(idCard);
在一对一关联中会自动先执行被关联对象的插入操作。这说明:
一对一关联默认了级联属性。
注意如果上面代码中把person.setIdCard(idCard);注释,那么会报NullPointerException
因为Person依赖IdCard为主键的,所以必须设置idCard属性
保存完之后加载
Person person = (Person)session.load(Person.class, 1); System.out.println(person.getName()); System.out.println(person.getIdCard().getCardNo());
生成 语句
Hibernate: /* load com.lwf.hibernate.pojo.Person */ select person0_.id as id3_0_, person0_.name as name3_0_ from Person person0_ where person0_.id=? zhangshang Hibernate: /* load com.lwf.hibernate.pojo.IdCard */ select idcard0_.id as id4_0_, idcard0_.cardNo as cardNo4_0_ from IdCard idcard0_ where idcard0_.id=? 1121212
删除:
Person person = (Person)session.load(Person.class, 1); session.delete(person);
将删除person表中id为1的列,删除不会删除与之关联的idCard表的的列。
如果:
IdCard idCard = (IdCard)session.load(IdCard.class, 3);
session.delete(idCard);
因为有Person表中的主键与之关联,所以删除报错,必须先删除Person表中对应的列。
双向关联:
上面我们加载的时候都是从person端加载,得到idCard
Person person = (Person)session.load(Person.class, 1); System.out.println(person.getName()); System.out.println(person.getIdCard().getCardNo());
那么能不能从idCard端加载,得到person呢
试一下:
IdCard idCard = (IdCard)session.load(IdCard.class,1); System.out.println(idCard.getPerson().getName());
输出结果:
报错
Hibernate: /* load com.lwf.hibernate.pojo.IdCard */ select idcard0_.id as id4_0_, idcard0_.cardNo as cardNo4_0_ from IdCard idcard0_ where idcard0_.id=? Exception in thread "main" java.lang.NullPointerException at com.lwf.hibernate.test.TestPerson.main(TestPerson.java:19)
这里我们需要实现一对一的双向关联:
我们只要在idcard的映射文件中加入one-to-one 即可。
如:
<?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 package="com.lwf.hibernate.pojo" > <class name="Person"> <id name="id"> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <property name="name"/> <one-to-one name="idCard" class="IdCard" constrained="true"></one-to-one> </class> <class name="IdCard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> <one-to-one name="person"></one-to-one> </class> </hibernate-mapping>
上面单向与双向双联我们只增加了:
<one-to-one name="person"></one-to-one>
对应person在IdCard Pojo类中定义属性:
private Person person;
并实现get与Set方法即可。
另一种一对一关联的方法是在配置文件中使用many-to-one,然后使用唯一属性
<many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one>
这也就唯一外键关联,在家里即person表中的主键有id和idCardId两个字段,但idCardId关联idCard表的id字段,并且在person表中的idCardId是唯一的。
如我们把上例的配置文件改成:
<?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 package="com.lwf.hibernate.pojo" > <class name="Person"> <id name="id"> <generator class="native"/> </id> <property name="name"/> <many-to-one name="idCard" class="IdCard" column="idCardId" unique="true"></many-to-one> </class> <class name="IdCard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> </class> </hibernate-mapping>
对应的表结构:
mysql> desc person; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | id | int(11) | NO | PRI | NULL | | | name | varchar(255) | YES | | NULL | | | idCardId | int(11) | YES | UNI | NULL | | +----------+--------------+------+-----+---------+-------+ 3 rows in set (0.01 sec) mysql> desc idcard; +--------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +--------+--------------+------+-----+---------+----------------+ | id | int(11) | NO | PRI | NULL | auto_increment | | cardNo | varchar(255) | YES | | NULL | | +--------+--------------+------+-----+---------+----------------+ 2 rows in set (0.02 sec)
保存
public static void save(Session session){ IdCard idCard = new IdCard(); idCard.setCardNo("1121212"); session.save(idCard); Person person = new Person(); person.setIdCard(idCard); person.setName("zhangshang"); session.save(person); }
注意在使用many-to-one的时候默认级联属性为false,所以上面要先使用session.save(idCard);
再使用session.save(person);保存。
而上面的one-to-one的时候默认级联属性为true,所以不需要先session.save(idCard);
保存之后数据表如下:
mysql> select * from person; +----+------------+----------+ | id | name | idCardId | +----+------------+----------+ | 1 | zhangshang | 1 | +----+------------+----------+ 1 row in set (0.00 sec) mysql> select * from idcard; +----+---------+ | id | cardNo | +----+---------+ | 1 | 1121212 | +----+---------+ 1 row in set (0.00 sec)
双向关联:
只要在idcard对应的配置中加入:
<one-to-one name="person" class="Person" property-ref="idCard"></one-to-one>
修改后的配置文件如下:
<?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 package="com.lwf.hibernate.map"> <class name="Person"> <id name="id"> <generator class="native"/> </id> <many-to-one name="idCard" column="idCardId" unique="true"/> <property name="name"/> </class> <class name="IdCard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> <one-to-one name="person" class="Person" property-ref="idCard"></one-to-one> </class> </hibernate-mapping>
测试从person取得idCard的数据:
Person person = (Person)session.load(Person.class, 2); System.out.println(person.getName()); System.out.println(person.getIdCard().getCardNo());
测试双向,从idCard取得person的数据:
IdCard idCard = (IdCard)session.load(IdCard.class, 1); System.out.println(idCard.getCardNo()); System.out.println(idCard.getPerson().getName());
发表评论
-
Hibernate抓取策略二
2010-05-11 17:56 1070在Classes与Student一对多映射中,我们将Set里面 ... -
Hibernate抓取策略一
2010-05-11 16:29 1315抓取策略指多表关联查询的时候,Hibernate会发出多条sq ... -
Hibernate查询缓存
2010-05-11 01:15 1611二级缓存中,如果不设置“查询缓存”,那么hibernate只会 ... -
Hibernate所需完整类库
2010-05-11 01:08 884附件为最新配置Hibernate所需的包. 由来: 一、下 ... -
Hibernate 二级缓存缺少包出现的异常
2010-05-10 23:29 2325由于二级缓存使用的包org.hibernate.cache.E ... -
转:Hibernate性能优化之二级缓存
2010-05-10 17:28 1132http://chenhongbin007.blog.163. ... -
Hibernate lazy加载FOR 单端关联
2010-05-10 00:54 1309Hibernate单端关联懒加载策略:即在<one-to ... -
Hibernate lazy加载FOR Connection
2010-05-10 00:28 1185Hibernate集合属性的懒加载策略: 在集合属性上, ... -
Hibernate lazy加载FOR Class
2010-05-09 23:51 1040lazy策略可以用在: * <class>标签 ... -
Hibernate性能优化:二级缓存
2010-05-06 16:48 1060hibernate二级缓存 定义步骤: 1、打开缓存, ... -
Hibernate性能优化:一级缓存
2010-05-06 16:33 1114一级缓存与session周期一致,二级缓存与sessionFa ... -
Hibernate悲观锁与乐观锁及事务管理机制
2010-05-06 11:57 1180引用: 悲观锁与乐观锁: http://www.iteye ... -
Hibernate学习笔记博客
2010-05-06 11:32 716网上也有人自学hibernate的笔记 http://hi. ... -
Hibernate与EJB的区别
2010-05-05 18:09 865Hibernate不支持分布式应用 -
Hibernate对象状态
2010-05-05 17:48 1767Hibernate对象有三种状态: 瞬时状态(Transie ... -
Hibernate HQL示例十二:DML更新、删除及与Hibernate持久化更新
2010-05-05 16:42 1964DML更新及删除 示例: package com.bjsx ... -
Hibernate HQL示例十一:分页查询
2010-05-05 16:21 1129分页查询: select * from t_student ... -
Hibernate HQL示例十:统计查询
2010-05-05 15:57 2108统计函数的使用 count(*) 等 package co ... -
Hibernate HQL示例九:连接查询
2010-05-05 15:38 3533inner join left out join rig ... -
Hibernate HQL示例八:查询对象导航及Implicit Join
2010-05-05 10:32 1680通过Student对象导航到class对象的id 如下: ...
相关推荐
本主题聚焦于“Hibernate双向一对一关联映射”的注解实现,这是一种高级的数据库设计模式,用于处理两个实体之间一对一的关系。 在Hibernate中,一对一关联映射分为单向和双向。单向一对一映射通常涉及一个实体持有...
一对一关联映射是指两个实体类之间存在一对一的关系,即每个实体实例对应数据库中的一条记录,且这条记录在另一张表中也有唯一对应的记录。在 MyBatis 中,我们可以通过 XML 映射文件或者注解来配置这种关联关系。 ...
在本篇关于MyBatis框架的学习中,我们将深入探讨一对一关联映射和一对多关联映射的概念、配置以及在实际开发中的应用。MyBatis是一个优秀的持久层框架,它允许开发者将SQL语句直接写在XML配置文件或者注解中,从而...
在Java开发中,Mybatis作为一款轻量级的持久层框架,被广泛应用于数据访问操作。本主题将详细探讨如何在Mybatis中实现...总之,正确配置Mybatis的映射文件和Java实体类,可以轻松地实现数据库中一对一关联的查询操作。
本资源主要探讨的是“hibernate一对一关联关系”。 一对一关联关系在现实世界中很常见,比如一个人只有一个身份证,或者一个公司的总部只有一个。在Hibernate中,设置一对一关联关系可以帮助我们更好地管理和操作...
本篇文章将深入探讨两种实现一对一关联的方式:主键关联(Primary Key Join)和唯一外键关联(ForeignKey Join),并结合源码和实际工具进行详细讲解。 一、主键关联(Primary Key Join) 1. 主键关联的概念: ...
本文将深入探讨基于外键的一对一关联查询,并通过具体的代码示例进行解析。 ### 1. 基于外键的一对一关联 在一对一关联中,外键方式是指在一个实体类中引用另一个实体类的主键作为外键。这种方式下,关联关系的...
本话题主要探讨的是Hibernate中的一对一关联映射,这是一种将数据库中的单个表映射到Java对象模型中单个类的关系映射技术。通过注解方式实现一对一关联映射,可以避免传统的XML配置文件,使得代码更加简洁、易读。 ...
**标题:** Hibernate一对一关联映射 **描述:** 在Java开发中,Hibernate作为一款强大的对象关系映射(ORM)框架,极大地简化了数据库操作。一对一(OneToOne)关联映射是Hibernate提供的一种对象关系映射策略,它...
本示例将深入讲解如何在Hibernate中实现主键一对一关联映射,并通过代码示例进行解析。 一对一关联意味着在一个实体中,每个实例都唯一对应另一个实体的实例。这种关联可以通过共享主键(primary key)或外键...
在这个“Hibernate双向一对一关联映射(XML版)”的主题中,我们将深入探讨如何通过XML配置文件实现两个实体之间的一对一关系。 首先,我们需要理解一对一关联的概念。在数据库中,一对一关联意味着两个表中的每一...
**JPA 一对一关联关系源码详解** Java Persistence API (JPA) 是Java平台上的一个标准,用于管理和持久化对象到数据库。它提供了一种面向对象的方式来操作数据库,简化了数据库编程。在JPA中,一对一(OneToOne)...
本篇将详细探讨 Hibernate 之中的一对一关联映射,这是一种常见的关系数据库设计模式,在实际开发中经常被用到。 一对一关联映射在Hibernate中表示两个实体类之间存在一对一的关系,也就是说,每个实体类的对象只...
**一对一关联关系**在数据库设计中表示两个表之间存在唯一的对应关系,例如,一个人可能只有一个护照,或者一个员工只有一个职位。在Hibernate中,这种关系可以通过外键(Foreign Key)在一方或双方实体中实现。 **...
本教程将深入探讨MyBatis的一对一关联映射,帮助初学者更好地理解和应用这个功能。 在数据库设计中,一对一关联指的是两个表中的每一行都对应另一表中的唯一一行。例如,一个用户表和一个用户详情表,用户表存储...
- **唯一性约束**:在数据库层面,为了确保一对一关联,通常需要添加唯一性约束。例如,`IdCard`表的`person_id`列应具有唯一性约束。 以上就是关于Hibernate中一对一主键关联映射(单项关联)的详细解释。通过这种...
一对一关联在现实世界中很常见,例如一个人只有一个身份证,一个身份证也只能属于一个人。在数据库设计中,这种关系通常通过主键和外键的方式实现,其中一方的主键作为另一方的外键,确保了两表间的一对一关系。 二...
- 虽然一对一关联提供了便利,但过多的一对一关联可能会影响性能,因为每次查询可能涉及多个表,增加数据库访问的复杂性。因此,应谨慎设计实体间的关系。 8. **实例应用** - 在实际项目中,一对一关联常用于用户...