hibernate系列(四)一对一关联关系

简介:
以Person类和IDCard类为例,这里仅仅说一种一对一关联关系,即Person类拥有IDCard,但是IDCard不含Person类,数据库库的表如下:  
?
1
2
3
4
5
6
CREATE TABLE `hibernate`.`person` (
   `id` INT NOT NULL AUTO_INCREMENT,
   ` name ` VARCHAR (45) NULL ,
   `age` INT NULL ,
   `idcard_id` INT NULL ,
   PRIMARY KEY (`id`));

?
1
2
3
4
5
CREATE TABLE `hibernate`.`idcard` (
   `id` INT NOT NULL AUTO_INCREMENT,
   `number` INT NULL ,
   `content` VARCHAR (45) NULL ,
   PRIMARY KEY (`id`));

Person类如下:  
?
1
2
3
4
5
6
7
8
public class Person {
 
     private Long id;
     private String name;
     private Long age;
     private IDCard idCard;
//省略get、set方法
}

Person类对应的Person.hbm.xml映射文件为:  
?
1
2
3
4
5
6
7
8
9
10
< hibernate-mapping >
     < class name = "com.ligang.domain.Person" table = "person" >
         < id name = "id" column = "id" type = "long" >
             < generator class = "identity" />
         </ id >
         < property name = "name" column = "name" type = "string" />
         < property name = "age" column = "age" type = "long" />
         < many-to-one name = "idCard" class = "com.ligang.domain.IDCard" column = "idcard_id" cascade = "save-update" ></ many-to-one >
     </ class >
</ hibernate-mapping >

虽然是一对一但是,这种形式的一对一就是多对一的特例,所以仍然使用<many-to-one>的标签,其中的name指的是Person类的idCard属性,column指的是person表中的字段名为idcard_id,class指的是将IDCard类对应的表的主键的值作为idcard_id的值。cascade字段表示保存Person类时级联的保存IDCard类。 
下面看下IDCard类:
 
?
1
2
3
4
5
6
7
public class IDCard {
 
     private Long id;
     private Long number;
     private String content;
//省略get、set方法
}

IDCard类对应的IDCard.hbm.xml映射文件为:  
?
1
2
3
4
5
6
7
8
9
< hibernate-mapping >
     < class name = "com.ligang.domain.IDCard" table = "idcard" >
         < id name = "id" column = "id" type = "long" >
             < generator class = "identity" />
         </ id >
         < property name = "number" column = "number" type = "long" />
         < property name = "content" column = "content" type = "string" />
     </ class >
</ hibernate-mapping >

然后就是测试增添方法:  
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
     public void addPerson(){
         Session session=hibernateDao.getSession();
         Transaction tx=session.beginTransaction();
         
         Person p= new Person();
         p.setName( "张三" );
         p.setAge(122L);
         
         IDCard idCard= new IDCard();
         idCard.setNumber(123445L);
         idCard.setContent( "你是一个人" );
         
         p.setIdCard(idCard);
         
         session.save(p);
         
         tx.commit();
         session.close();
     }

此时就会先保存IDCard对象,然后获取其主键并赋值给person表的idcard_id字段,然后增添Person对象。如下sql:  
?
1
2
Hibernate: insert into hibernate.idcard (number, content) values (?, ?)
Hibernate: insert into hibernate.person ( name , age, idcard_id) values (?, ?, ?)

更新如下:  
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test
     public void updatePerson(){
         Session session=hibernateDao.getSession();
         Transaction tx=session.beginTransaction();
         
         Person p=(Person) session.get(Person. class ,6L);
         p.setName( "张三" );
         p.setAge(122L);
         
         IDCard idCard= new IDCard();
         idCard.setNumber(123445L);
         idCard.setContent( "你是一个人" );
         
         p.setIdCard(idCard);
         
         session.save(p);
         
         tx.commit();
         session.close();
     }

此时的sql如下:  
?
1
2
3
Hibernate: select person0_.id as id1_3_0_, person0_. name as name2_3_0_, person0_.age as age3_3_0_, person0_.idcard_id as idcard_i4_3_0_ from hibernate.person person0_ where person0_.id=?
Hibernate: insert into hibernate.idcard (number, content) values (?, ?)
Hibernate: update hibernate.person set name =?, age=?, idcard_id=? where id=?

此时并没有删除原有的IDCard,只是根据Person再也找不到它了。目前我还不知道怎么设置来删除无用的IDCard。 

获取:由Person的主键获取IDCard比较容易,但是如果想从IDCard主键获取Person呢? 
首先更改IDCard类,添加person属性:
 
?
1
2
3
4
5
6
7
8
public class IDCard {
 
     private Long id;
     private Long number;
     private String content;
     private Person person;
//略get、set方法
}

然后更改上述的IDCard.hbm.xml映射文件如下:  
?
1
2
3
4
5
6
7
8
9
10
< hibernate-mapping >
     < class name = "com.ligang.domain.IDCard" table = "idcard" >
         < id name = "id" column = "id" type = "long" >
             < generator class = "identity" />
         </ id >
         < property name = "number" column = "number" type = "long" />
         < property name = "content" column = "content" type = "string" />
         < one-to-one name = "person" property-ref = "idCard" ></ one-to-one >
     </ class >
</ hibernate-mapping >

添加了<one-to-one>标签,同时使用了property-ref属性,看下查询再解释:  
?
1
2
3
4
5
6
7
8
9
10
11
@Test
     public void getPerson(){
         Session session=hibernateDao.getSession();
         Transaction tx=session.beginTransaction();
         
         IDCard idCard=(IDCard) session.get(IDCard. class ,2L);
         System.out.println(idCard.getPerson().getName());
         
         tx.commit();
         session.close();
     }

查询的sql如下:  
?
1
2
Hibernate: select idcard0_.id as id1_1_0_, idcard0_.number as number2_1_0_, idcard0_.content as content3_1_0_, person1_.id as id1_3_1_, person1_. name as name2_3_1_, person1_.age as age3_3_1_, person1_.idcard_id as idcard_i4_3_1_ from hibernate.idcard idcard0_ left outer join hibernate.person person1_ on idcard0_.id=person1_.idcard_id where idcard0_.id=?
张三

将Person查出来了,然后看下他是怎么查的,看下IDCard的<one-to-one name="person" property-ref="idCard">,name指的是IDCard的person属性,而property-ref指向了另一个类的属性,这里就是Person类的idCard属性,要想查出Person总要告诉hibernate idcard表的哪个字段和person表的哪个字段相连接吧,这里的property-ref="idCard",即指定了要和Person类的idCard属性所对应的字段相连接,默认是采用主键来和该字段相连接的,我不知道能否指定。即idcard表的主键id和Person类的idCard属性对应的字段idcard_id相连接,来查询Person,看sql语句:hibernate.idcard idcard0_ left outer join hibernate.person person1_ on idcard0_.id=person1_.idcard_id 

上述一对一的关联关系是通过外键来连接,他们也可以使用相同的主键实现一对一。这里不再讲述。 

相关文章
|
6月前
|
SQL Java 数据库连接
Hibernate -双向一对一关联关系映射
Hibernate -双向一对一关联关系映射
53 0
|
XML 存储 Java
Hibernate框架【三】——基本映射——一对一映射
Hibernate框架【三】——基本映射——一对一映射
78 0
|
XML Java 数据库连接
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
67 0
《Hibernate上课笔记》-----class5----Hibernate实现一对一关联映射
|
SQL Java 数据库连接
【SSH快速进阶】——Hibernate一对一映射(one-to-one)——唯一外键关联
  接着上篇文章,唯一外键关联,就是给一对一关联关系中某个对象加一个外键。比如这里给t_person表添加一个外键,指向t_idcard的主键,并且规定t_person中的外键idCard唯一,也可以达到一对一映射的效果。
【SSH快速进阶】——Hibernate一对一映射(one-to-one)——唯一外键关联
|
SQL Java 数据库连接
【SSH快速进阶】——Hibernate一对一映射(one-to-one)——主键关联映射
 现实生活中,有很多场景需要用到一对一映射,比如每个学生只有一个学生证,每个公民只有一张身份证等。这里用公民-身份证来举例说明。
【SSH快速进阶】——Hibernate一对一映射(one-to-one)——主键关联映射
|
SQL Java 数据库连接
Hibernate的一对一映射(八)
Hibernate的一对一映射(八)
113 0
Hibernate的一对一映射(八)
|
SQL NoSQL Java
hibernate(五) hibernate一对一关系映射详解
之前讲解了一对多(单向、双向)、多对多(双向),今天就讲解一下最后一个关系,一对一。 心情不错。状态也挺好的,赶紧写一篇博文造福一下大家把。  
285 0
|
Java 关系型数据库 数据库连接
|
Java 关系型数据库 数据库连接