关?于?h?i?b?e?r?n?a?t?e?中?双?向?外?键?关?联?o?n?e?-?t?o?-?o?n?e?的?p?r?o?p?e?r?t?y?-?r?e?f?=?的?问?题(转)

大家都知道hibernate中的one-to-one映射主要有两种策略,(1)一对一主键关联(单向和双向)。(2)一对一外键映射(单项和双向)。本文主要讲解一下,一对一外键映射中的双向问题,在此前先通过一个实例了解。

person和idCard,是一种一对一的关系,其中
 
t_person表

id       
name       idCard(unique)
1         张三

2         王五       1

其中王五是没有idcard,这也符合现实中的,有些人是没有身份证的。
t_idCard表
id         cardNo
1    11111111111111

实体类:
IdCard
package com.bjpowernode.hibernate;

public class IdCard {

private int id;

private String cardNo;

private Person person;

public Person getPerson() {
return person;
}

public void setPerson(Person person) {
this.person = person;
}

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;
}

}

Person
package com.bjpowernode.hibernate;

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 String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public IdCard getIdCard() {
return idCard;
}

public void setIdCard(IdCard idCard) {
this.idCard = idCard;
}
}

(3)配置文件
   IdCard的:
  <?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.bjpowernode.hibernate">
<class name="IdCard" table="t_idCard">
<id name="id">
<generator class="native"/>
</id>
<property name="cardNo"/>
<one-to-one name="person"  class="Person" 
/>
</class>
</hibernate-mapping>

Person的:

<?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.bjpowernode.hibernate">
<class name="Person" table="t_person">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
<many-to-one name="idCard" cascade="all"
class="IdCard" unique="true" column="card_ID" />
</class>
</hibernate-mapping>
(3)
向t_person中插入数据:
import org.hibernate.Session;

import junit.framework.TestCase;

public class One2OneTest extends TestCase {

public void testSave1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();

Person person = new Person();
person.setName("张三");

session.save(person);
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
结果如下:
mysql> select * from t_person;
+----+------+---------+
| id | name | card_ID |
+----+------+---------+
|  1 | 张三 |    NULL |
+----+------+---------+
1 row in set (0.00 sec)

mysql> select * from t_idcard;
Empty set (0.00 sec)

在插入数据:
public void testSave2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();

IdCard idCard = new IdCard();
idCard.setCardNo("1111111111");
session.save(idCard);

Person person = new Person();
person.setName("王五");
//建立关联
person.setIdCard(idCard);

session.save(person);

session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
数据库中的结果如下:
mysql> select * from t_person;
+----+------+---------+
| id | name | card_ID |
+----+------+---------+
|  1 | 张三 |    NULL |
|  2 | 王五 |       1 |
+----+------+---------+
2 rows in set (0.00 sec)

mysql> select * from t_idcard;
+----+------------+
| id | cardNo     |
+----+------------+
|  1 | 1111111111 |
+----+------------+
1 row in set (0.00 sec)
(4)加载数据,这样的话就可以从person的一端加载到idCard,
如下:
public void testLoad1() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
Person person = (Person)session.load(Person.class, 2);
System.out.println("person.name=" + person.getName());
System.out.println("person.cardNo="
+                  
person.getIdCard().getCardNo());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
结果如下:
    Hibernate: select person0_.id as id0_0_, person0_.name as
name0_0_, person0_.card_ID as card3_0_0_ from t_person person0_ where
person0_.id=?
person.name=王五
        Hibernate: select idcard0_.id as
id1_1_, idcard0_.cardNo as cardNo1_1_, person1_.id as id0_0_, person1_.name as
name0_0_, person1_.card_ID as card3_0_0_ from t_idCard idcard0_ left outer join
t_person person1_ on idcard0_.id=person1_.id where idcard0_.id=?
    person.cardNo=1111111111 这样的就找到了person对应的idcard,那能不能有idCard找到person呢?

public void testLoad2() {
Session session = null;
try {
session = HibernateUtils.getSession();
session.beginTransaction();
//

IdCard idCard = (IdCard)session.load(IdCard.class, 1);
System.out.println("idCard.cardNo=" + idCard.getCardNo());
System.out.println("idCard.person.name=" +
idCard.getPerson().getName());
session.getTransaction().commit();
}catch(Exception e) {
e.printStackTrace();
session.getTransaction().rollback();
}finally {
HibernateUtils.closeSession(session);
}
}
结果如下:
Hibernate: select idcard0_.id as id1_1_, idcard0_.cardNo as cardNo1_1_,
person1_.id as id0_0_, person1_.name as name0_0_, person1_.card_ID as
card3_0_0_ from t_idCard idcard0_ left outer join t_person person1_ on
idcard0_.id=person1_.id where idcard0_.id=?
idCard.cardNo=1111111111
idCard.person.name=张三
结果对吗?
  肯定不对,idCard.cardNo=1111111111这是王五的idCard,怎么查出来张三的呢?原因在于:

idCard的配置文件问题:
应该在idCard的配置文件的<one-to-one name="person" 
class="Person"  />
修改为<one-to-one name="person" 
class="Person"  property-ref="idCard"/>
因为:如果不修改则idCard会根据自己的id和person中的id比较(因为one-to-one是通过id查找到的),这样是不符合要求的,因为我们t_idcard中的id和t_person中 Card_ID相比较,这样的话可以通过
property-ref="idCard" 的设置找到t_person表中Card_ID和它作比较找到我们要找的数据。

关?于?h?i?b?e?r?n?a?t?e?中?双?向?外?键?关?联?o?n?e?-?t?o?-?o?n?e?的?p?r?o?p?e?r?t?y?-?r?e?f?=?的?问?题(转)

时间: 2024-10-16 07:18:35

关?于?h?i?b?e?r?n?a?t?e?中?双?向?外?键?关?联?o?n?e?-?t?o?-?o?n?e?的?p?r?o?p?e?r?t?y?-?r?e?f?=?的?问?题(转)的相关文章

m?y?e?c?l?i?p?s?e? ?环?境?下?整?合?开?发? ?s?t?r?u?t?s?2?+?s?p?r?i?n?g?+?h?i?b?e?r?n?a?t?e? ?常?见?问?题?及?解?答

myeclipse 环境下整合开发 struts2+spring+hibernate 常见问题及解答 1. org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): 异常原因: <id> 元素配置不正确, <id> 元素缺少其子元素 <generator></generator> 的配

s?q?l? ?s?e?r?v?e?r? ?2?0?0?0?登?录?名?与?数?据?库?用?户?名?的?关?联?问?题

MS SQL Server 2000 数据库使用备份还原造成的孤立用户和对象名'xxx'无效的错误的解决办法     在使用数据库的过程中,经常会遇到数据库迁移或者数据迁移的问题,或者有突然的数据库损坏,这时需要从数据库的备份中直接恢复.但是,此时会出现问题,这里说明几种常见问题的解决方法.  一.孤立用户的问题比如,以前的数据库的很多表是用户test建立的,但是当我们恢复数据库后,test用户此时就成了孤立用户,没有与之对应的登陆用户名,哪怕你建立了一个test登录用户名,而且是以前的用户密码

J?a?v?a?S?c?r?i?p?t?针?对?D?o?m?相?关?的?优?化?心?得

JavaScript针对Dom相关的优化心得 组内同时总结的关于javascript性能优化注意些节.记录一下. 1. 批量增加 Dom 尽量使用修改 innerHTML 的方式而不是用 appendChild 的方式 ; 因为使用 innerHTML 开销更小 , 速度更快 , 同时也更加内存安全 . 有一点需要注意的是 , 用 innerHTML 方式添加时 , 一定不要在循环中使用 innerHTML += 的方式添加 , 这样反而会使速度减慢 ; 而是应该中间用 array 缓存起来 ,

SQL Server 触发器例题: --次性删除course表数据,使用触发器替换删除操作,先删除外键表相关数据,再删除course。很难理解

create trigger Course_Delete on course instead of delete as declare @cno varchar(20) --定义变量 select @cno = cno from deleted --临时表里的信息是instead of 替换 delete要删除的信息 delete from score where cno = @cno --instead of 替换操作后执行的代码命令 delete from course where cno=

【猜牌问题】甲乙都知道桌子的抽屉里有16张扑克牌: 红桃A、Q、4 黑桃J、8、4、2、7、3 草色K、Q、5、4、6 方块A、5 教授从这16张牌中挑出一张牌来,并把这张牌的点数告诉甲,把这张牌的花色告诉乙。教授问:你们能推理出是什么牌吗? 甲:我不知道这张牌。 乙:我知道你不知道这张牌。 甲:现在我知道这张牌了。 乙:我也知道了。 请问:这张牌是什么牌?

甲乙都知道桌子的抽屉里有16张扑克牌: 红桃A.Q.4 黑桃J.8.4.2.7.3 草色K.Q.5.4.6 方块A.5 教授从这16张牌中挑出一张牌来,并把这张牌的点数告诉甲,把这张牌的花色告诉乙.教授问:你们能推理出是什么牌吗? 甲:我不知道这张牌.乙:我知道你不知道这张牌.甲:现在我知道这张牌了.乙:我也知道了. 请问:这张牌是什么牌? 解: 教授告知甲点数,告知乙花色 人物 已知 未知 甲 A 红桃.方块 Q 红桃.草色 4 红桃.黑桃.草色 J 黑桃 8 黑桃 2 黑桃 7 黑桃 3 黑

R语言在联通数据分析中的运用

最近在参加一个大数据竞赛,将R语言学习记录写在这里. 1.打开csv数据 df<-read.csv('PhoneChange.csv', header=TRUE) 2.数据筛选 ARPU_Null=df[df$ARPU值段=="",] 3.描述性统计分析 summary(df) summary(df$年龄值段)

替换html里面的\r\n及解决记事本中的每个段落只有一行的情形

1. 在用python爬取小说的时候, 发现在内容里每次换行都有\r\n(即回车, 换行)出现. 此时可以采用  s.replace('\\r\\n','') , 其中s为字符串类型. 2. 在爬取完小说内容后, 用记事本打开时每个段落无论长短都只占一行, 此时可以点击记事本上方的 '格式' --> '自动换行' 解决. 原文地址:https://www.cnblogs.com/DSYR/p/10317375.html

第 四 十 三 天:Apache 的 相 关 问 题

小Q:人生的意志和劳动将创造奇迹般的奇迹.       -- 涅克拉索夫 apache设置自定义header----------------------------------------- 1. 在设置自定义header前,需要先检测一下你的httpd是否加载了mod_headers /usr/local/apache2/bin/apachectl  -l 否则需要重新编译一下了 2.  在httpd.conf 中加入 <IFModule mod_headers.c> Header add

第 四 十 二 天:samba 的 相 关 问 题

小Q:世界上一成不变的东西,只有"任何事物都是在不断变化的"这条真理.--斯里兰卡 samba端口-------------------------------------------------------------- 1)Port 137 (UDP) - NetBIOS 名字服务 : nmbd 2)Port 138 (UDP) - NetBIOS 数据报服务 3)Port 139 (TCP) - 文件和打印共享 : smbd (基于SMB(Server Message Block