关于OneToOne的一些话题

本文通过实战案例介绍了Hibernate框架中OneToOne关联映射的具体应用,包括数据的读写、更新和删除操作,并对比了不同场景下产生的SQL语句及其效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于hibernate的OneToOne我在实际的项目中并没有真正的使用过,这里只是做一些简单的了解,假设有如下两个数据库表:
IDCARDS[id varchar2(64) not null,
        card_no varchar2(100) not null,
        person_id varchar2(64) not null
       ]
person[id varchar2(64) not null,varchar2(100) name]
当前可以确定的操作有:
     读数据:
         读取person,
         读取idcard,
     写数据:
         写person信息到数据库中
         写idcard信息到数据库
     更新数据:
         更新person数据
         更新idcard信息数据
     删除数据:
         删除person数据信息
         删除idcard数据信息 
        
    统计数据:           
        统计person的总数
       
按照上面的需求,设计类文件如下,这里我们选择使用OneToOne: 
  1. @Entity  
  2. @Table(name="IDCARDS")   
  3. public class IDCard implements Serializable {   
  4.     private static final long serialVersionUID = 1L;   
  5.     private String id;   
  6.     private String cardNo;   
  7.     private Person person;      
  8.     /**  
  9.      * @return Returns the person.  
  10.      */  
  11.     @OneToOne(optional=true,cascade=CascadeType.ALL,fetch=FetchType.LAZY)   
  12.     @JoinColumn(name="person_id")   
  13.     public Person getPerson() {   
  14.         return person;   
  15.     }   
  16.        ......   
  17. }   
  18.   
  19. @Entity  
  20. @Table(name="persons")   
  21. public class Person implements Serializable {   
  22.     private static final long serialVersionUID = 1L;   
  23.     private String id;   
  24.     private String name;   
  25.     private IDCard idCard;   
  26.        
  27.     /**  
  28.      * @return Returns the idCard.  
  29.      */  
  30.     @OneToOne(optional=true,cascade=CascadeType.ALL,mappedBy="person",fetch=FetchType.LAZY)   
  31.     public IDCard getIdCard() {   
  32.         return idCard;   
  33.     }   
  34.          .......   
  35. }  
写数据的测试:
  1. public static void testOneToOne3(){   
  2.     Person person = new Person();   
  3.     person.setId("0001");   
  4.     person.setName("snowflower");   
  5.     IDCard card  = new IDCard();   
  6.     card.setId("123456");   
  7.     card.setCardNo("123456789012");   
  8.     card.setPerson(person);   
  9.     Transaction tx = session.beginTransaction();   
  10.     tx.begin();   
  11.     session.save(person);   
  12.     session.save(card);   
  13.     session.flush();   
  14.        tx.commit();   
  15. }  
这种情况下执行的语句为:

 
更新数据:
  1. public static void testOneToOne4(){   
  2.     IDCard card = (IDCard)session.load(IDCard.class,"123456");   
  3.     if(card != null){   
  4.         card.setCardNo("new"+card.getCardNo());   
  5.     }   
  6.     Transaction tx = session.beginTransaction();   
  7.     tx.begin();   
  8.     session.update(card);   
  9.     session.flush();   
  10.     tx.commit();   
  11. }  

在这里尝试更新IDCard的数据信息时hibernate产生的sql语句为:
Hibernate: select idcard0_.id as id2_1_,
        idcard0_.card_no as card2_2_1_,
idcard0_.person_id as person3_2_1_,
person1_.id as id1_0_,
person1_.name as name1_0_
from
IDCARDS idcard0_
left outer join
persons person1_
on
idcard0_.person_id=person1_.id where idcard0_.id=?
Hibernate: select idcard0_.id as id2_1_,
idcard0_.card_no as card2_2_1_,
idcard0_.person_id as person3_2_1_,
person1_.id as id1_0_,
person1_.name as name1_0_
from
IDCARDS idcard0_
left outer join
persons person1_
on
idcard0_.person_id=person1_.id where idcard0_.person_id=?
Hibernate: update IDCARDS set card_no=?, person_id=? where id=?
感觉更新了一个IDCard的编号却牵连到如此语句,从某中意义上说,一条update语句足够了…………
为了改变更新的效率尝试如下的做法:
  1. public static void testOneToOne4(){   
  2.     Person person = (Person)session.load(Person.class,"0001");   
  3.     IDCard card = person.getIdCard();   
  4.     Transaction tx = session.beginTransaction();   
  5.     tx.begin();   
  6.     card.setCardNo("new"+card.getCardNo());   
  7.     session.update(card);   
  8.     session.flush();   
  9.     tx.commit();   
  10. }  
使用此种方法后生成的语句为:
Hibernate: select person0_.id as id1_1_,
                                person0_.name as name1_1_,
                                idcard1_.id as id2_0_,
                                idcard1_.card_no as card2_2_0_,
                                idcard1_.person_id as person3_2_0_
                   from
                                persons person0_
                   left outer join
                                IDCARDS idcard1_
                   on 
                                person0_.id=idcard1_.person_id where person0_.id=?
Hibernate: update IDCARDS set card_no=?, person_id=? where id=?
这里需要注意的一点就是,如果IDCard数据没有改变的话是不会产生update语句的
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值