Hibernate04
Hibernate基于Annotation的配置
Annotation在架構中是越來越受歡迎了,因為annotation的配置比起XML的配置來說友善了很多,不需要大量的XML來書寫,友善簡單了很多,隻要幾個annotation的配置,就可以完成我們以前需要書寫的大量的XML檔案。當然annotation的配置也有缺陷的,那就是annotation一般都是配置在代碼中的,如果要修改的話,需要動源代碼,喪失了靈活性,違背了OCP(增加開放,修改關閉)原則,但是在真實的項目開發中,我們隻是動配置檔案,而不修改源代碼的情況實在是太少見了,是以現在annotation已經被廣泛的運用到了程式設計中,各種架構都提供了基于annotation的配置。
下面我們來看看hibernate基于annotation的配置吧,在學之前,我們需要知道一些hibernate關于annotation的常識:
1、 hibernate中的annotation是基于JPA這個包的,如果是4.0之前的版本,hibernate的required檔案夾下,沒有jpa的包,需要去jpa檔案夾下加入jpa的包
2、 在hibernate的3.5之前需要下載下傳hibernate的annotation的jar包
3、 在3.5之前如果使用annotation,建立Configuration是需要使用AnnotationConfiguration()來建立。
4、 在3.5之後可以直接使用Configuration來建立(不用管哪種——annotation或者XML)
使用annotation配置
Annotation的配置使得我們的項目配置檔案大大的減少,是以annotation的配置現在在各種架構中的使用越來越廣泛,下面我就是用annotation來試試吧。
第一個annotation配置的hibernate項目
我們就以我們以前的user案例來配置annotation版本的hibernate項目吧。
建立User.java類,注意看annotation的配置:
package com.lzcc.hibernate.entity; import java.util.Date; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="t_user") publicclass User { privateintid; private String username; private String password; private String nickname; private Date bornDate; @Id @GeneratedValue() publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getUsername() { returnusername; } publicvoid setUsername(String username) { this.username = username; } public String getPassword() { returnpassword; } publicvoid setPassword(String password) { this.password = password; } public String getNickname() { returnnickname; } publicvoid setNickname(String nickname) { this.nickname = nickname; } @Column(name="born_date") public Date getBornDate() { returnbornDate; } publicvoid setBornDate(Date bornDate) { this.bornDate = bornDate; } public User() { } public User(int id, String username, String password, String nickname, Date bornDate) { super(); this.id = id; this.username = username; this.password = password; this.nickname = nickname; this.bornDate = bornDate; } public User(String username, String password, String nickname, Date bornDate) { super(); this.username = username; this.password = password; this.nickname = nickname; this.bornDate = bornDate; } @Override public String toString() { return"User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname + ", bornDate=" + bornDate + "]"; } } |
之後在hibernate.cfg.xml檔案中加入這個實體類(注意:和配置檔案相同的是也是使用mapping引入,但是不同的是使用class屬性,并且不是斜杠,而是點):
<!-- 使用annotation的配置,不再使用resource,而是使用class,注意也不再是斜杠,而是點 --> <mapping class="com.lzcc.hibernate.entity.User"/> |
寫單元測試類:
@Test publicvoid testAdd() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); User u = new User("laomu", "123", "老孫", DateUtil.getDate("1994-12-23")); session.save(u); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); session.getTransaction().rollback(); } finally { HibernateUtil.closed(session); } } |
運作我們發現和使用配置檔案一樣,運作成功。
這就是使用annotation來配置hibernate,我們發現比起XML的配置來說,hibernate的annotation的确比較友善了許多。這個隻是單表配置,下面我們來看看many-to-one的配置吧。
annotation配置many-to-one單向
還是使用我們前面的案例來講解:
Student.java:
package com.lzcc.hibernate.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name="t_stu") publicclass Student { privateintid; private String name; private String stuNo; private ClassRoom classRoom; @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public String getStuNo() { returnstuNo; } publicvoid setStuNo(String stuNo) { this.stuNo = stuNo; } @ManyToOne @JoinColumn(name="cid") public ClassRoom getClassRoom() { returnclassRoom; } publicvoid setClassRoom(ClassRoom classRoom) { this.classRoom = classRoom; } public Student() { } public Student(int id, String name, String stuNo, ClassRoom classRoom) { super(); this.id = id; this.name = name; this.stuNo = stuNo; this.classRoom = classRoom; } public Student(String name, String stuNo, ClassRoom classRoom) { super(); this.name = name; this.stuNo = stuNo; this.classRoom = classRoom; } @Override public String toString() { return"Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + classRoom + "]"; } } |
ClassRoom.java:
package com.lzcc.hibernate.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.Table; @Entity @Table(name="t_cls_room") publicclass ClassRoom { privateintid; private String name; @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public ClassRoom() { } public ClassRoom(int id, String name) { super(); this.id = id; this.name = name; } @Override public String toString() { return"ClassRoom [id=" + id + ", name=" + name + "]"; } } |
将兩個實體類加入到hibernate的配置檔案中:
<!-- 使用annotation的配置,不再使用resource,而是使用class,注意也不再是斜杠,而是點 --> <mapping class="com.lzcc.hibernate.entity.User"/> <mapping class="com.lzcc.hibernate.entity.Student"/> <mapping class="com.lzcc.hibernate.entity.ClassRoom"/> |
運作測試代碼:
@Test publicvoid testAdd01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); //我們先添加一方,再添加多方 ClassRoom c = new ClassRoom(); c.setName("梁山班"); session.save(c); Student stu1 = new Student("宋江", "001", c); session.save(stu1); Student stu2 = new Student("吳用", "003", c); session.save(stu2); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
我們發現配置來說,annotation配置相當的簡單,比起XML檔案的配置來說要簡單了很多的。
添加來說,annotation和XML配置的都一樣,如果先一方,多方後添加,則符合我們的想法,會發送相應的sql數量,如果先添加多方,則會多發送幾條更新外鍵的sql。
@Test publicvoid testAdd02() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); //如果我們先添加多的一方呢? Student stu1 = new Student(); stu1.setName("孫悟空"); stu1.setStuNo("001"); session.save(stu1); Student stu2 = new Student(); stu2.setName("豬八戒"); stu2.setStuNo("002"); session.save(stu2); ClassRoom c = new ClassRoom(); c.setName("西遊班"); session.save(c); stu1.setClassRoom(c); stu2.setClassRoom(c); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
當我們測試下面代碼時發現報錯了:
@Test publicvoid testAdd03() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); //我們先添加一方,再添加多方 ClassRoom c = new ClassRoom(); c.setName("紅樓班"); Student stu1 = new Student("賈寶玉", "001", c); session.save(stu1); Student stu2 = new Student("林黛玉", "003", c); session.save(stu2); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
和XML配置一樣,因為我們這樣需要強制關聯,那麼annotation的強制關聯怎麼寫?
這樣就不報錯了,但是我們前面就說過,cascade我們一般是不會使用的,隻有一些特殊情況才會使用,如在删除一方時,需要關聯删除多方時,這些特殊才會使用,但是基本我們也不會這樣使用,因為我們要删除時,需要自己控制代碼的運作,那麼我們一般會在業務層自己寫邏輯代碼來完成。
@Test publicvoid testLoad01() { Session session = null; try { session = HibernateUtil.openSession(); Student stu = (Student) session.load(Student.class, 1); System.out.println(stu.getName()); System.out.println(stu.getClassRoom().getName()); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
運作代碼,我們發現基于annotation的配置,load方法沒有延遲加載,那麼如果我們想要延遲加載的話,需要這樣配置:
此時運作代碼:
延遲加載就有了,至于到底使用不使用延遲加載,這個就要根據項目的實際情況而定了。
annotation配置many-to-one雙向
雙向的配置和單向很類似,隻是在一方設定一個存放多方的集合。
其實hibernate的annotation配置many-to-one的單向和雙向很是類似,下面我們就以上面的案例來實作雙向配置。
Student.java,多方配置跟單向的一樣:
package com.lzcc.hibernate.entity; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name="t_stu") publicclass Student { privateintid; private String name; private String stuNo; private ClassRoom classRoom; @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public String getStuNo() { returnstuNo; } publicvoid setStuNo(String stuNo) { this.stuNo = stuNo; } @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="cid") public ClassRoom getClassRoom() { returnclassRoom; } publicvoid setClassRoom(ClassRoom classRoom) { this.classRoom = classRoom; } public Student() { } public Student(int id, String name, String stuNo, ClassRoom classRoom) { super(); this.id = id; this.name = name; this.stuNo = stuNo; this.classRoom = classRoom; } public Student(String name, String stuNo, ClassRoom classRoom) { super(); this.name = name; this.stuNo = stuNo; this.classRoom = classRoom; } @Override public String toString() { return"Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + ", classRoom=" + classRoom + "]"; } } |
ClassRoom.java:
package com.lzcc.hibernate.entity; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="t_cls_room") public class ClassRoom { private int id; private String name; private Set<Student> students; @OneToMany(mappedBy="classRoom") public Set<Student> getStudents() { return students; } public void setStudents(Set<Student> students) { this.students = students; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public ClassRoom() { } public ClassRoom(int id, String name) { super(); this.id = id; this.name = name; } @Override public String toString() { return "ClassRoom [id=" + id + ", name=" + name + "]"; } } |
測試代碼:
@Test publicvoid testAdd01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Student stu1 = new Student(); stu1.setName("曹操"); stu1.setStuNo("001"); session.save(stu1); Student stu2 = new Student(); stu2.setName("劉備"); stu2.setStuNo("002"); session.save(stu2); ClassRoom c = new ClassRoom(); c.setName("三國班"); Set<Student> stus = new HashSet<Student>(); stus.add(stu1); stus.add(stu2); c.setStudents(stus); session.save(c); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
運作結果如下:
測試load方法:
@Test publicvoid testLoad() { Session session = null; try { session = HibernateUtil.openSession(); ClassRoom c = (ClassRoom) session.load(ClassRoom.class, 5); System.out.println(c.getName()); System.out.println(c.getStudents().size()); Student s = (Student) session.load(Student.class, 10); System.out.println(s.getName()); System.out.println(s.getClassRoom().getName()); } catch (Exception e) { e.printStackTrace(); } finally { HibernateUtil.closed(session); } } |
我們發現annotation的配置延遲加載預設不存在了,因為annotation的配置出現的比較晚,這時候hibernate的開發團隊發現延遲加載在分層體系中的确不再有那麼好的優勢,而且因為延遲加載的問題導緻hibernate的異常難用,是以預設就不在提供延遲加載了,當然如果想使用延遲加載也行,在many-to-one的annotation中加入就行了:
@ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="cid") public ClassRoom getClassRoom() { returnclassRoom; } |
除此之外,我們發現了一個問題,如果我們想查詢集合或者對應關系的數量時,還是沒有使用count(*)這種計數函數,如果我們想要使用的話(當然,如果延遲加載不使用,不建議使用,因為沒有延遲加載隻會發送一條sql,而加上配置,則會單獨的發一條sql完成),可以配置如下:
@OneToMany(mappedBy="classRoom") @LazyCollection(LazyCollectionOption.EXTRA) public Set<Student> getStudents() { returnstudents; } |
注意在one-to-many中加入LazyCollection的annotation中加入extar值,在運作代碼,我們發現的确計數使用了count函數:
但是我們也看出了,多發送了一條sql,是以annotation配置hibernate的話,如果不手動開啟延遲加載,不建議開啟這個配置。
annotation配置one-to-one雙向
還是以person和IDCard為例:
Persion.java:
package com.lzcc.hibernate.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name = "t_person") publicclass Person { privateintid; private String name; private IDCard idCard; @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } @OneToOne(mappedBy = "person") public IDCard getIdCard() { returnidCard; } publicvoid setIdCard(IDCard idCard) { this.idCard = idCard; } public Person() { } public Person(int id, String name, IDCard idCard) { super(); this.id = id; this.name = name; this.idCard = idCard; } public Person(String name, IDCard idCard) { super(); this.name = name; this.idCard = idCard; } public Person(String name) { super(); this.name = name; } @Override public String toString() { return"Person [id=" + id + ", name=" + name + ", idCard=" + idCard + "]"; } } |
IDCard.java:
package com.lzcc.hibernate.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; import javax.persistence.Table; @Entity @Table(name="t_id_card") publicclass IDCard { privateintid; private String no; private Person person; @OneToOne @JoinColumn(name="pid") public Person getPerson() { returnperson; } publicvoid setPerson(Person person) { this.person = person; } @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getNo() { returnno; } publicvoid setNo(String no) { this.no = no; } public IDCard() { } public IDCard(String no) { super(); this.no = no; } public IDCard(int id, String no) { super(); this.id = id; this.no = no; } @Override public String toString() { return"IDCard [id=" + id + ", no=" + no + "]"; } } |
此時運作代碼:
@Test publicvoid testAdd01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); IDCard card = new IDCard("110120"); session.save(card); //将IDCard設定到使用者屬性中,表示這個一個一對一的關聯 //表示張三的身份證号碼為:110120 Person p = new Person("張三", card); session.save(p); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
代碼成功運作,但是我們發現外鍵沒有被關聯插入,這是因為annotation的配置中我們明确規定了不由Person端維護關系,有IDCard端的person字段維護關系,那麼我們如果要插入資料,必須先有Person,這樣IDCard插入資料時才有person字段的id完成外鍵關聯。是以,注意:一對一的annotation配置後,一定要先插入不維護關系的一方。
那麼我們先插入不維護關系的一端:
@Test publicvoid testAdd02() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Person p = new Person("張三 "); session.save(p); IDCard card = new IDCard("110120"); card.setPerson(p); session.save(card); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
成功的完成了插入。
annotation配置many-to-many
在hibernate中many-to-many這種配置我們不會使用,我們前面就說過,many-to-many我們會分解為兩個many-to-one來配置,下面的代碼緊緊供參考。
User.java:
package com.lzcc.hibernate.entity; import java.util.Date; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name="t_user") public class User { private int id; private String username; private String password; private String nickname; private Date bornDate; private Set<Role> roles; @ManyToMany(mappedBy="users") public Set<Role> getRoles() { return roles; } public void setRoles(Set<Role> roles) { this.roles = roles; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public String getNickname() { return nickname; } public void setNickname(String nickname) { this.nickname = nickname; } public Date getBornDate() { return bornDate; } public void setBornDate(Date bornDate) { this.bornDate = bornDate; } public User() { } public User(int id, String username, String password, String nickname, Date bornDate) { super(); this.id = id; this.username = username; this.password = password; this.nickname = nickname; this.bornDate = bornDate; } public User(String username, String password, String nickname, Date bornDate) { super(); this.username = username; this.password = password; this.nickname = nickname; this.bornDate = bornDate; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", password=" + password + ", nickname=" + nickname + ", bornDate=" + bornDate + "]"; } } |
Role.java:
package com.lzcc.hibernate.entity; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.JoinTable; import javax.persistence.ManyToMany; import javax.persistence.Table; @Entity @Table(name="t_role") public class Role { private int id; private String name; private Set<User> users; @ManyToMany @JoinTable(name="t_user_role",joinColumns={@JoinColumn(name="rid")}, inverseJoinColumns={@JoinColumn(name="uid")}) public Set<User> getUsers() { return users; } public void setUsers(Set<User> users) { this.users = users; } @Id @GeneratedValue public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Role() { } public Role(String name) { this.name = name; } public Role(int id, String name) { super(); this.id = id; this.name = name; } @Override public String toString() { return "Role [id=" + id + ", name=" + name + "]"; } } |
這就是多對多的配置,但是不建議使用它,我們多對多都是由兩個一對多來完成,下面我來看看吧。
annotation配置many-to-many變種
還是以前面的案例來說
Student.java:
package com.lzcc.hibernate.entity; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name = "stu") publicclass Student { privateintid; private String name; private String stuNo; private Set<StudentCourse> tcs; @OneToMany(mappedBy="stu") public Set<StudentCourse> getTcs() { returntcs; } publicvoid setTcs(Set<StudentCourse> tcs) { this.tcs = tcs; } @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public String getStuNo() { returnstuNo; } publicvoid setStuNo(String stuNo) { this.stuNo = stuNo; } public Student() { } public Student(int id, String name, String stuNo) { this.id = id; this.name = name; this.stuNo = stuNo; } public Student(String name, String stuNo) { this.name = name; this.stuNo = stuNo; } @Override public String toString() { return"Student [id=" + id + ", name=" + name + ", stuNo=" + stuNo + "]"; } } |
Course.java:
package com.lzcc.hibernate.entity; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.OneToMany; import javax.persistence.Table; @Entity @Table(name="t_course") publicclass Course { privateintid; private String name; private Set<StudentCourse> tcs; @OneToMany(mappedBy="course") public Set<StudentCourse> getTcs() { returntcs; } publicvoid setTcs(Set<StudentCourse> tcs) { this.tcs = tcs; } @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } public String getName() { returnname; } publicvoid setName(String name) { this.name = name; } public Course() { } public Course(int id, String name) { this.id = id; this.name = name; } public Course(String name) { this.name = name; } } |
TeacherCourse.java:
package com.lzcc.hibernate.entity; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.Table; @Entity @Table(name="t_stu_course") publicclass StudentCourse { privateintid; privatedoublescore; private Student stu; private Course course; @Id @GeneratedValue publicint getId() { returnid; } publicvoid setId(int id) { this.id = id; } publicdouble getScore() { returnscore; } publicvoid setScore(double score) { this.score = score; } @ManyToOne @JoinColumn(name="sid") public Student getStu() { returnstu; } publicvoid setStu(Student stu) { this.stu = stu; } @ManyToOne @JoinColumn(name="cid") public Course getCourse() { returncourse; } publicvoid setCourse(Course course) { this.course = course; } public StudentCourse() { } public StudentCourse(int id, double score, Student stu, Course course) { super(); this.id = id; this.score = score; this.stu = stu; this.course = course; } } |
運作測試代碼:
@Test publicvoid testAdd01() { Session session = null; try { session = HibernateUtil.openSession(); session.beginTransaction(); Student s1 = new Student(); s1.setName("劉建宏"); s1.setStuNo("001"); session.save(s1); Student s2 = new Student(); s2.setName("劉帥哥"); s2.setStuNo("002"); session.save(s2); Course c1 = new Course(); c1.setName("Java in Action"); session.save(c1); Course c2 = new Course(); c2.setName("PHP in Action"); session.save(c2); StudentCourse tc = new StudentCourse(); tc.setScore(88); tc.setStu(s1); tc.setCourse(c1); session.save(tc); tc = new StudentCourse(); tc.setScore(99); tc.setStu(s1); tc.setCourse(c2); session.save(tc); tc = new StudentCourse(); tc.setScore(100); tc.setStu(s2); tc.setCourse(c2); session.save(tc); tc = new StudentCourse(); tc.setScore(60); tc.setStu(s2); tc.setCourse(c1); session.save(tc); session.getTransaction().commit(); } catch (Exception e) { e.printStackTrace(); if (session != null) { session.getTransaction().rollback(); } } finally { HibernateUtil.closed(session); } } |
我們發現結果完全一樣,而且在關系表中我們可以加入一些其他的字段,這樣才是我們做多對多關聯的,我們在使用hibernate的時候,會将多對多分解為兩個多對一來完成。
總結
Hibernate引入annotation的時間比較晚,是以annotation的配置相對來說比較好用點,因為hibernate将延遲加載等問題都屏蔽掉了(如果想使用,可以配置),是以在将來的項目中,建議如下:
1、 如果是小型項目,建議使用annotation的配置,簡單友善
2、 如果是大型項目(百萬行代碼量及以上),建議使用hibernate