Hibernate多表關係配置

  • 2019 年 10 月 4 日
  • 筆記

Hibernate多表關係配置

1.表的關係

2.一對多配置

3.級聯操作

4.多對多配置

5.多對多操作

1

表的關係

表之間的關係

一對多(一個部門有多個員工,一個員工只能屬於某一個部門)

多對多(一個老師教多個學生,一個學生可以被多個老師教)

一對一(一個公司只能對應一個註冊地址)

表之間關係建表原則

一對多(在多的一方創建一個外鍵,指向一的一方的主鍵)

多對多(創建一個中間表,中間表至少有兩個欄位,分別作為外鍵指向多對多雙方的主鍵)

一對一(唯一外鍵對應或主鍵對應)

2

一對多配置

1.建表(班級、學生)

class_id

class_name

numbers

stu_id

stu_name

stu_age

class_id

2.建立ORM

domain類

@Getter@Setter  public class Classes {      private Integer class_id;      private String class_name;      private Integer class_student;      //一個班級包含多個學生      private Set<Student> students = new HashSet<>();  }
@Setter@Getter  public class Student {      private Integer stu_id;      private String stu_name;      private Integer stu_age;      //一個學生屬於一個班級      private Classes stu_class;  }

映射文件

映射文件中普通欄位段的配置不用寫上外鍵,在一的一方配置文件寫上set標籤name屬性為關聯屬性名,裡面還有key標籤有column屬性關係中的外鍵即另一個表的外鍵欄位名,還有一個標籤one-to-many寫上另一表的domain類全路徑。在多的一方只有一個many-to-one標籤裡面name屬性也是關聯屬性名,class屬性關係表它的domain地址,還有一個column外鍵

<hibernate-mapping>      <class name="com.hao.domain.Classes" table="classes">            <id name="class_id" >              <generator class="identity"/>          </id>          <property name="class_name"/>          <set name="students">              <key column="class_id"></key>              <one-to-many class="com.hao.domain.Student"></one-to-many>          </set>      </class>  </hibernate-mapping>
<hibernate-mapping>  <class name="com.hao.domain.Student" table="student">        <id name="stu_id">          <generator class="identity"/>      </id>      <property name="stu_name" />      <property name="stu_age" />      <many-to-one name="stu_class" class="com.hao.domain.Classes" column="class_id" lazy="false"></many-to-one>  </class>  </hibernate-mapping>

3.添加核心配置文件

<mapping resource="com/hao/domain/Student.hbm.xml"/>  <mapping resource="com/hao/domain/Classes.hbm.xml"/>

4.編寫測試類

    public void saveTest() {          Session session = HibernateUtil.openSession();          Transaction tra = session.beginTransaction();          //創建三個班級          Classes c1 = new Classes();          Classes c2 = new Classes();          Classes c3 = new Classes();          c1.setClass_name("c1");          c2.setClass_name("c2");          c3.setClass_name("c3");          //創建三個學生          Student s1 = new Student();          Student s2 = new Student();          Student s3 = new Student();          s1.setStu_name("張三");          s2.setStu_name("李四");          s3.setStu_name("王五");          //班級1添加兩個學生,班級2添加一個學生          c1.getStudents().add(s1);          c1.getStudents().add(s2);          c2.getStudents().add(s3);          //保存全部          session.save(s1);          session.save(s2);          session.save(s3);          session.save(c1);          session.save(c2);          session.save(c3);            tra.commit();      }

結果

class_id

class-name

numbers

1

c1

null

2

c2

null

3

c3

null

stu_id

stu_name

stu_age

class_id

1

s1

null

1

2

s2

null

1

3

s3

null

2

默認是先保存各自的內容,再建立連接(添上外鍵),刪除也是先去掉外鍵再刪除。接下來通過級聯操作實現關聯關係表同步更新

3

級聯操作

按照上面的操作保存3個班級3個學生,共六條保存

理論上只保存一邊是可行的。

比如只保存班級c1、c2、c3,它們添加了s1、s2、s3。

所以添加班級也會在學生表中添加對應的記錄。

但是實際上會報錯——瞬時對象異常

這是因為保存的對象關聯了處於瞬時態的對象

我們可以在配置文件中去開啟級聯操作

在哪個配置文件去開啟,就在它對應的domain保存時才有級聯

在Classes的映射文件去添加cascade,保存classes時就會級聯保存不用再單獨去保存student,關聯資訊本來在classes就有

 <set name="students" cascade="save-update">     <key column="class_id" ></key>     <one-to-many class="com.hao.domain.Student" ></one-to-many>   </set>

還可以寫在Student的映射文件,這樣保存student就會同時保存關聯的classes資訊

<many-to-one  cascade="save-update" name="stu_class" class="com.hao.domain.Classes" column="class_id" lazy="false" ></many-to-one>

在更新時也會有級聯操作,當classes移除一個學生,那麼student表會變

還有刪除,當刪除一個班級,那麼student表中屬於這個班的student也會全刪掉

cascade="delete"

4

多對多配置

配置和一對多一樣,只是set標籤中多一個table屬性值為中間關係表的表名

建表

course_id

course_name

stu_id

stu_name

stu_age

class_id

stu_id

course_id

建立ORM

domain類

@Setter@Getter  public class Student {      private Integer stu_id;      private String stu_name;      private Integer stu_age;      //一個學生有多門課程      private set<Course> courses;  }
@Setter@Getter  public class Course {      private Integer Course_id;      private String Course_name;      //一個課程有眾多學生學習      private set<Student> students;  }

映射文件

<set name="courses" table="c-s" cascade="save-update,delete">    <key column="stu_id"></key>    <many-to-many class="com.hao.domain.Course" column="course_id"></many-to-many>  </set>
<set name="students" table="c-s">    <key column="course_id"></key>    <many-to-many class="com.hao.domain.Student" column="stu_id"></many-to-many>  </set>

最後再在核心配置文件載入上映射文件

<mapping resource="com/hao/domain/Course.hbm.xml"/>

編寫測試

@Test  public void manytomany(){    Course c1 = new Course();    Course c2 = new Course();    Course c3 = new Course();    c1.setCourse_name("語文");    c2.setCourse_name("數學");    c3.setCourse_name("英語");      Student s1 = new Student();    Student s2= new Student();    Student s3 = new Student();    s1.setStu_name("張三");    s2.setStu_name("李四");    s3.setStu_name("王五");      c1.getStudents().add(s1);    c1.getStudents().add(s2);    c1.getStudents().add(s3);    c2.getStudents().add(s1);    c3.getStudents().add(s2);    c3.getStudents().add(s3);      Session session = HibernateUtil.openSession();    Transaction tra = session.beginTransaction();    session.save(c1);    session.save(c2);    session.save(c3);    tra.commit();  }

5

多對多操作

對多對的操作雙方的關係都在中間表上,都在各自得關聯集合中。所以它們得操作就是操作集合

給上面王五添加數學課

@Test  public void manytomany(){    Session session = HibernateUtil.openSession();    Transaction tra = session.beginTransaction();    //獲取王五    Student stu = session.get(Student.class,1);    //獲取數學課    Course course = session.get(Course.class,2)    //修改集合    stu.getCourses().add(course);    tra.commit();  }

其他也是一樣

給王五刪除數學課

@Test  public void manytomany(){    Session session = HibernateUtil.openSession();    Transaction tra = session.beginTransaction();    //獲取王五    Student stu = session.get(Student.class,1);    //獲取數學課    Course course = session.get(Course.class,2)    //修改集合    stu.getCourses().remove(course);    tra.commit();  }

給王五把英語課改為數學課(其實就是前面的刪除和添加)

@Test  public void manytomany(){    Session session = HibernateUtil.openSession();    Transaction tra = session.beginTransaction();    //獲取王五    Student stu = session.get(Student.class,1);    //獲取英語課    Course course1 = session.get(Course.class,3);    //獲取數學課    Course course2 = session.get(Course.class,2);    //修改集合    stu.getCourses().remove(course1);    stu.getCourses().add(course2);    tra.commit();  }

特別注意:事務提交、建表引擎(坑)

Tags: