天天看點

Hibernate(四)基于注解annotation的配置Hibernate04Hibernate基于Annotation的配置使用annotation配置第一個annotation配置的hibernate項目annotation配置many-to-one單向annotation配置many-to-one雙向annotation配置one-to-one雙向annotation配置many-to-manyannotation配置many-to-many變種總結

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

繼續閱讀