hibernate inverse解析(双向一对多)

Customer.class

public class Customer
{
 private int id;
 private String name;
 private Order order;

.......//get**,set**省略

}

对应的.hdm.xml

<class name="model.Customer" table="T_customer">
  <id name="id" column="customer_id">
   <generator class="native"/>
  </id>
  <property name="name" column="customername"></property>
  <many-to-one name="order"  column="o_id" class="model.Order" >
  </many-to-one>

</class>

 

Order.class

public class Order
{
 private int id;
 private Set<Customer> set=new HashSet<Customer>();
 private String number;
 
 private Customer customer;

.......//get**,set**省略

}

对应的hbm.xml

<class name="model.Order" table="T_order">
   <id name="id" column="id" >
           <generator class="native"/>
  </id>
  <property name="number" column="product_number"></property>
  <set name="set" inverse="false" cascade="all">    //可以添加table指向T_customer,
   <key column="o_id"></key>                                  //在T_customer表中的外键(o_id)与本表主键关联

                                                                                    //可以与T_customer表外键不相同,但这样可能(看代码怎么写)会使T_customer表有两个外键,所以最好相同!

   <one-to-many class="model.Customer" />             //这里是表示映射本类(Order)类中customer字段
  </set>  
</class>

 

对应以上配置文件

Customer c1=new Customer();
  Customer c2=new Customer();
  c1.setName("Callo");
  c2.setName("jack");
  c1.setOrder(order);
  c2.setOrder(order);  //注释1
  order.getSet().add(c1);
  order.getSet().add(c2);

上面的代码会使Hibernate执行五条SQL语句,其中前三条是insert插入语句,后两条是update更新语句。

插入就不用说了,

问:那么为什么还要有更新语句呢?

答:这是因为Order类映射文件的<set>元素中指定了inverse="false",这就告之Hibernate:T_order表与T_Customer表的主外键关系是由Order类来维护的。当执行save后,执行了三条insert语句,这三条语句中的后两条是插入到T_customer表的,它们的o_id字段是通过c1.getOrder().getId()取出的,假如我将上面“注释1”处修改为c2.setOrder(order2)(其实这违反了一对多的约定);(order2是另一个Order对象,可能是持久化对象),这样,主外键关系不就乱了吗。为了保证主外键关系,Hibernate在这种情况下会再执行两条update语句来更改T_Cusromer表中两个新插入记录的o_id字段,当然,这时o_id字段的取值是从order对象中直接取得,而不再是c1.getOrder().getId()方式了。
如果我们将Order类映射文件的<set>元素中的inverse属性修改为true,这就是告诉Hibernate:Order类不维护主外键关系了,这个任务就交给了Customer类。于是,我们再执行上面的代码,Hibernate就会只执行三条insert语句,而不会执行任何update语句。因为Hibernate会通过Customer类的c1.getOrder().getId()和c2.getOrder().getId()来确定o_id字段的值。

  
故,为了节省数据库资源,省却不必要的update语句,我们一般建议在一对多双向关联关系中,将一方的inverse属性设置为true,即将主外键的关系交由多方来维护。
打个比方:在一个公司中,是老板认识所有的员工容易,还是所有员工认识老板容易?

控制台输出:

 create table T_customer (
        customer_id int identity not null,
        customername varchar(255) null,
        o_id int null,
        primary key (customer_id)
    )
15:21:36,343 DEBUG SchemaExport:377 -
    create table T_order (
        id int identity not null,
        product_number varchar(255) null,
        primary key (id)
    )
15:21:36,343 DEBUG SchemaExport:377 -
    alter table T_customer
        add constraint FK519FCF69DC2CA314
        foreign key (o_id)
        references T_order
15:21:36,343  INFO SchemaExport:268 - schema export complete
Hibernate:
    insert
    into
        T_order
        (product_number)   
    values
        (?)
Hibernate:
    insert
    into
        T_customer
        (customername, o_id)      //c1.getOrder().getId()
    values
        (?, ?)
Hibernate:
    insert
    into
        T_customer
        (customername, o_id)     //c2.getOrder().getId()
    values
        (?, ?)
Hibernate:
    update
        T_customer
    set
        o_id=?
    where
        customer_id=?
Hibernate:
    update
        T_customer
    set
        o_id=?
    where
        customer_id=?

  

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本方法。编译原理不仅是计算机科学理论的重要组成部分,也是实现高效、可靠的计算机程序设计的关键。本文将对编译原理的基本概念、发展历程、主要内容和实际应用进行详细介绍编译原理是计算机专业的一门核心课程,旨在介绍编译程序构造的一般原理和基本

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值