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關係。但還要根據實際情況加以選擇。