inverse經常用在雙向的1—N關聯之中,也可以用在N—N的關聯,這裏舉例子用雙向的1—N關聯
還是用部門和員工兩個,關於兩個的javabean不再寫。
首先,我們看下員工的映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="cn.itcast.hibernate.domain">
<class name="Employee" table="tb_Employee">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<many-to-one name="depart" column="depart_id" />
</class>
</hibernate-mapping>
然後,是部門的映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="cn.itcast.hibernate.domain">
<class name="Department" table="tb_Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<set name="emps">
<key column="depart_id" />
<one-to-many class="Employee" />
</set>
</class>
</hibernate-mapping>
此時,在部門的映射文件的set標籤中,我們未用inverse屬性,接下來我們寫一個測試類看看情況:
package cn.itcast.hibernate;
import java.util.HashSet;
import java.util.Set;
import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction;
import cn.itcast.hibernate.domain.Department;
import cn.itcast.hibernate.domain.Employee;
public class Many2One {
public static void main(String[] arg){
Department depart = add();
}
static Department add(){
Session s = null;
Transaction tx = null;
try{
Department depart = new Department();
Department depart1 = new Department();
depart.setName("depart name");
Employee emp1 = new Employee();
emp1.setDepart(depart); //建立兩個對象的關聯關係
emp1.setName("emp name");
Employee emp2 = new Employee();
emp2.setDepart(depart); //建立兩個對象的關聯關係
emp2.setName("emp name");
Set<Employee> emps = new HashSet<Employee>();
emps.add(emp1);
emps.add(emp2);
depart.setEmps(emps);
s = HibernateUtil.getSession();
tx = s.beginTransaction();
s.save(depart);
s.save(emp1);
s.save(emp2);
System.out.println(depart.getEmps().size());
tx.commit();
return depart;
}finally{
if(s!=null){
s.close();
}
}
}
}
我們看下程序:首先建立了一個Department對象,並建立了兩個Employee對象,並且分別爲這兩個Employee對象設置depart。然後,我們建立了一個Set集合存放這兩個Employee對象,然後把這個集合注入給Department對象depart。現在,在數據庫中是一對多,在Hibernate關係中,部門可以知道有哪些員工,員工知道屬於哪個部門。
我們看一下MyEclipse打印出來的sql語句:
Hibernate: insert into tb_Department (name) values (?)
Hibernate: insert into tb_Employee (name, depart_id) values (?, ?)
Hibernate: insert into tb_Employee (name, depart_id) values (?, ?)
2
Hibernate: update tb_Employee set depart_id=? where id=?
Hibernate: update tb_Employee set depart_id=? where id=?
我們看到,第一、二、三行是三條插入語句,分別插入1個Department和2個Employee,在第四行打印出來了Department對象擁有的員工的size()個數。但是在最下邊兩行出現了兩條update語句,這兩條update語句是我們在代碼中把set集合注入給Department對象depart:
當雙向1—N關聯的時候,1的一端想要維護關係,N的一端也想要維護關係,在1的一端先插入,N的一端後插入之後,還要爲N的一端外鍵再更新成爲1的一端的id。所以會多出兩條update語句。
但是,如果我們在部門映射文件中的set標籤加入inverse="true"的屬性後,這兩條update語句就會消失,我們修改下部門映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
package="cn.itcast.hibernate.domain">
<class name="Department" table="tb_Department">
<id name="id">
<generator class="native"/>
</id>
<property name="name" />
<set name="emps" inverse="true" >
<key column="depart_id" />
<one-to-many class="Employee" />
</set>
</class>
</hibernate-mapping>
我們再測試一下會打印出哪些sql語句:
Hibernate: insert into tb_Department (name) values (?)
Hibernate: insert into tb_Employee (name, depart_id) values (?, ?)
Hibernate: insert into tb_Employee (name, depart_id) values (?, ?)
2
這裏的兩條update語句已經是不見了。
這是因爲1的一端不再控制關聯關係。
inverse=“true”表明1的一端不再控制關聯關係