天天看點

【SSH三大架構】Hibernate基礎第十篇:inverse屬性詳解

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的一端不再控制關聯關系

繼續閱讀