1. 程式人生 > >Hibernate中,mappedBy和註解@JoinColumn的對比

Hibernate中,mappedBy和註解@JoinColumn的對比

mappedBy

我們知道,mappedBy用於指定具有雙向關係的兩個實體中。哪個實體是被關聯處理的。它有如下四個特點:

1.只有OneToOne,OneToMany,ManyToMany上才有mappedBy屬性,ManyToOne不存在該屬性;

[email protected](mapped=“由One的一方指向Many的一方,並且,這個屬性應該等於Many的一方中含有One類的屬性的物件名,否則會出錯”)

3.關係的擁有方(即Many的一方)負責關係的維護,在擁有方建立外來鍵。所以用到@JoinColumn

4.mappedBy跟JoinColumn/JoinTable總是處於互斥的一方

mappedBy和@JoinColumn的對比

但是,在使用@OneToMany註解的時候,為了讓One知道Many中的物件的哪個欄位來關聯自己的時候,在Many的一方,我們既可以用@OneToMany的mappedBy指向一個物件變數,也可以用@JoinColumn指向One的一個外來鍵欄位。

例如:一個年級有多個學生,其中顯然是:年級(one)學生(many)

學生(ManyToOne):

1 //學生  
2 public class Student {  
3   
4     @ManyToOne  
5     @JoinColumn(name = "grade_id")  
6         private Grade   grade;  
7    
8         //get和set方式省略  
9 }

年級(OneToMany):

mappedBy方式:

1 //年級  
2 public class Grade {  
3 
4     @OneToMany(mappedBy = "grade", cascade = CascadeType.ALL)  
5     private Set<Student>  students;  
6     
7   //get和set方式省略  
8 }  

以上Grade使用@OneToMany註解通過mappedBy指定了集合中的物件Student是通過grade屬性關聯到Grade的。 同時設定了cascade為CascadeType.ALL,當某個grade中進行操作時也會級聯對集合中student進行同樣的操作,需要注意的是必須為集合中的student設定garde屬性為當前需要操作的grade,否則新增的student的外來鍵為空。

@JoinColumn方式:

1 public class Grade {  
2   
3     @OneToMany(cascade = CascadeType.ALL)  
4     @JoinColumn(name = "grade_id")  
5     private Set<Student>  students;  
6   
7     //get和set方式省略  
8 }  

以上Grade是通過宣告@JoinColumn指定了集合中的Student通過外來鍵grade_id關聯到當前的Grade的,當設定Cascade的時候,當對某個grade進行某種操做時也會級聯對集合中的student進行同樣的操作,同時還會對集合中新增的物件進行一次update操作,以保證集合中的物件有外來鍵關鍵到當前物件,因此可以不一定要設定student指向grade。 需要注意的是,如果沒有設定級聯,但是集合中有未儲存的student,對grade進行操作時,會報異常,org.springframework.dao.InvalidDataAccessApiUsageException: object references an unsaved transient instance - save the transient instance before 當進行級聯操作時,相當於發出瞭如下的update語句來維護many中的物件和one關係:

update  t_student  set  grade_id=?  where  id=?  

查閱資料對比得知,或許用mappedBy更好,因為當進行級聯操作時,不會發出更多的update語句來維護many中的物件和one關係。但還要根據實際情況加以選擇。