您的位置:首页 > 其它

Hibernate 中 元素的inverse 属性分析

2010-07-25 08:18 274 查看
试验背景:

表:

create table order_7(
id number primary key,
order_number varchar2(30),
customer_id number)

alter table order_7
drop column customer_id

alter table order_7
add constraint customer_id_fk customer_id references customer(id);

CREATE TABLE  CUSTOMERS
(	ID NUMBER,
NAME VARCHAR2(20) NOT NULL ENABLE,
PRIMARY KEY (ID) ENABLE
)


Customer.java

package com.liuxi.examples;

import java.util.HashSet;
import java.util.Set;

import com.sun.org.apache.bcel.internal.generic.NEW;

public class Customer {
private Long id;
private String name;

private Set<Order> orders = new HashSet<Order>();

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

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

public Set<Order> getOrders() {
return orders;
}

public void setOrders(Set<Order> orders) {
this.orders = orders;
}

}


Order.java

package com.liuxi.examples;

import java.util.HashSet;
import java.util.Set;

import com.sun.org.apache.bcel.internal.generic.NEW;

public class Customer {
private Long id;
private String name;

private Set<Order> orders = new HashSet<Order>();

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

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

public Set<Order> getOrders() {
return orders;
}

public void setOrders(Set<Order> orders) {
this.orders = orders;
}

}


Customer.hbm.xml

<hibernate-mapping>
<class name="com.liuxi.examples.Customer" table="CUSTOMERS" schema="HIBERNATE">
<id name="id" column="ID" type="java.lang.Long">
<generator class="increment"/>
</id>
<property name="name" column="NAME" type="java.lang.String"/>

<set name="orders"  cascade="save-update delete"  inverse="true" >
<key column="CUSTOMER_ID"/>
<one-to-many class="com.liuxi.examples.Order"/>
</set>
</class>
</hibernate-mapping>


Order.hbm.xml

<hibernate-mapping>
<class name="com.liuxi.examples.Order" table="ORDER_7" schema="HIBERNATE">
<id name="id" column="ID" type="java.lang.Long">
<generator class="increment"/>
</id>
<property name="orderNumber" column="ORDER_NUMBER" type="java.lang.String"/>
</class>
</hibernate-mapping>


级联保存与Customer对象相关的Order对象:

SessionFactory sessionFactory = HibernateSessionFactoryUtil
.getSessionFactory();
Session session = sessionFactory.getCurrentSession();
Transaction tx = session.beginTransaction();

Order order = new Order();
order.setOrderNumber("1234567");

Customer customer = new Customer();
customer.setName("马云");
customer.getOrders().add(order);

try {
session.save(customer); // 级联保存与customer对象关联的order对象
tx.commit();
} catch (Exception e) {
tx.rollback();
}


如果Customer.hbm.xml中set元素的属性inverse为true,则控制台输出的信息为:

Hibernate:
select
max(ID)
from
CUSTOMERS
Hibernate:
select
max(ID)
from
ORDER_7
Hibernate:
insert
into
HIBERNATE.CUSTOMERS
(NAME, ID)
values
(?, ?)
Hibernate:
insert
into
HIBERNATE.ORDER_7
(ORDER_NUMBER, ID)
values
(?, ?)


如果Customer.hbm.xml中set元素的属性inverse为false(默认是false),则控制台输出的信息为:

Hibernate:
insert
into
HIBERNATE.CUSTOMERS
(NAME, ID)
values
(?, ?)
Hibernate:
insert
into
HIBERNATE.ORDER_7
(ORDER_NUMBER, ID)
values
(?, ?)
Hibernate:
update
HIBERNATE.ORDER_7
set
CUSTOMER_ID=?
where
ID=?


发现这时,多执行了一条update语句。Why?

inverse=false分析:

当修改了Customer 对象的属性:

customer.getOrders().addOrder(order)

Hibernate 一旦知道持久态对象customer的上面的属性发生变化,执行相应的SQL语句:

update
HIBERNATE.ORDER_7
set
CUSTOMER_ID=?
where
ID=?

但如果将inverse=true,则customer与order之间的关系的控制被反转了,

Hibernate 监测到Customer对象上的属性发生变化,并不会去更新与该Customer对象相关的order记录。因为控制被反转了,

one 的一方(Customer)你变你的,我(Order)不会因为你的变化而被Hibernate控制,因为控制反转了,控制权不在你Customer一方,哈哈。我(many 一方)独立了!!

这样一来,我们在应用程序开发过程中为了提高性能,最好是在“one"方把<set>元素的inverse属性设置为true.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: