Hibernate多对一与一对多

 1. 多对一(多的一方是主动方)

<many-to-one name= "category"  class = "com.tazi.domin.Category"  lazy= "false"  fetch= "join" >
      <column name= "CATEGORY_ID"  />
</many-to-one>

 当设定fetch="join"或outer-join="true"时,在get/load时,Hibernate使用左外连接(left outer join)来查询。默认情况下,先查询主表,再根据外键查询关联表的字段值。
例子:Product与Category(类别)是多对一的关系

1
2
3
4
5
6
7
Product product= new  Product();
product.setName( "台灯2" );
product.setPrice( 262 .3f);
Category category= new  Category();
category.setName( "生活用品" );
category.setDescription( "小小的" );
product.setCategory(category);

 当使用session.save(product)时会报错,在未设置级联(cascade)的情况下,Hibernate不会先保存Category(一的一方)的记录,所以要先使用session.save(category)再保存product;

 2.一对多关联(多的一方为主动方)
同样的,如果是Category(一的一方)维护关系,也需要先保存关联表才能保证正确性

category.getProducts().add(product1);
category.getProducts().add(product2);
session.save(product1); //如果设置了cascade则该句和下一句不用写
session.save(product2);
session.save(category);

Hibernate SQL语句如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
Hibernate:
     insert
     into
         hib.product
         (NAME, PRICE, DESCRIPTION)
     values
         (?, ?, ?)
Hibernate:
     insert
     into
         hib.product
         (NAME, PRICE, DESCRIPTION)
     values
         (?, ?, ?)
Hibernate:
     insert
     into
         hib.category
         (NAME, DESCRIPTION)
     values
         (?, ?)
Hibernate:
     update
         hib.product
     set
         CATEGORY_ID=?
     where
         ID=?
Hibernate:
     update
         hib.product
     set
         CATEGORY_ID=?
     where
         ID=?

注意:如果程序中交换保存的顺序,即session.save(一的一方)在先,session.save(多的一方在后),执行的结果是一样的。因为只要一的一方是主动维护关系(通过<set>与<one-to-many>),一的一方就有责任负责多的一方外键字段的更新。

 3.cascade="save-update"的作用

它的作用仅仅是方便程序员少写几行session.save()语句,仅此而已,在提高sql语句执行效率上并没有什么作用。

1
2
3
4
5
6
<set name= "products"  cascade= "save-update"  >
     <key>
         <column name= "CATEGORY_ID"  />
     </key>
     <one-to-many  class = "com.tazi.domin.Product"  />
</set>

此时原本需要写:session.save(多的一方)的语句现在可以不写。只要写session.save(一的一方)。

4.理解inverse=true的作用

1
2
3
4
5
6
<set name= "products"  cascade= "save-update"   inverse= "true"   >
            <key>
                <column name= "CATEGORY_ID"  />
            </key>
            <one-to-many  class = "com.tazi.domin.Product"  />
</set>

inverse=true意味着原本一的一方已经维护了关联关系,但现在它可以不管这些了,它保存或更新的时候可以不对多的一方负责任了。也就不会存在update外键字段这样的sql语句了。这个时候如果仍然只有一的一方维护关系(不论是在POJO中还是在映射配置文件中),那么多的一方的外键字段一定是null.此时必须让一的一方也建立关联关系,并且维护。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Product product= new  Product();
product.setName( "台灯2" );
product.setPrice( 262 .3f);
 
Product product2= new  Product();
product2.setName( "台灯3" );
product2.setPrice( 262 .3f);
 
Category category= new  Category();
category.setName( "生活用品" );
category.setDescription( "小小的" );
category.getProducts().add(product);
category.getProducts().add(product2);
 
product.setCategory(category);
product2.setCategory(category);

同时在一的一方配置文件中:

<many-to-one name= "category"  class = "com.tazi.domin.Category"  lazy= "false"  fetch= "join" >
             <column name= "CATEGORY_ID"  />
</many-to-one>

然后session.save(category)就可以了。Hibernate执行sql的效率提高,如下:

Hibernate:
     insert
     into
         hib.category
         (NAME, DESCRIPTION)
     values
         (?, ?)
Hibernate:
     insert
     into
         hib.product
         (CATEGORY_ID, NAME, PRICE, DESCRIPTION)
     values
         (?, ?, ?, ?)
Hibernate:
     insert
     into
         hib.product
         (CATEGORY_ID, NAME, PRICE, DESCRIPTION)
     values
         (?, ?, ?, ?)

这与直接由多的一方保存关联关系并维护的效果是一样的。


转自:http://www.cnblogs.com/tazi/archive/2011/12/12/2284190.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值