2014年1月13日 星期一

單向一對多 XML Mapping

如果今天考慮一對多的配置模式,

例如一個老師教很多位學生,

如下圖:















以老師(一)對應學生(多)的方式,

Student.java
package com.model;

public class Student {
 private String id;
 private String name;
 public String getId() {
  return id;
 }
 public void setId(String id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
}

Teacher.java
package com.model;

import java.util.Set;

public class Teacher {
 private String id;
 private String name;
 private Set students;

 public String getId() {
  return id;
 }

 public void setId(String id) {
  this.id = id;
 }

 public String getName() {
  return name;
 }

 public void setName(String name) {
  this.name = name;
 }

 public Set getStudents() {
  return students;
 }

 public void setStudents(Set students) {
  this.students = students;
 }

 public void addStudent(Student student) {
  this.students.add(student);
 }
}

Teacher類別裡有多了增加Student的function,

當然也有一個Student的set集合,

Student.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.model.Student" table="student">
  <id name="id" column="id">
   <generator class="assigned"/>
  </id>
  <property name="name" type="string">
   <column name="name" length="10" not-null="true" />
  </property>
 </class>
</hibernate-mapping>

Teacher.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
 <class name="com.model.Teacher" table="teacher">
  <id name="id" column="id">
   <generator class="assigned"/>
  </id>
  <property name="name" type="string">
   <column name="name" length="10" not-null="true" />
  </property>
  <set name="students" table="student" cascade="all">
   <key column="teacherId" />
   <one-to-many class="com.model.Student"/>
  </set>
 </class>
</hibernate-mapping>

用一個set集合配置對應很多學生,

其中的key-column為table student裡與teacher的對應欄位,

接著撰寫測試程式:

TestStudentTeacher.java
package com.hibernate;

import java.util.HashSet;

import org.hibernate.Session;
import org.hibernate.Transaction;

import com.hibernate.util.HibernateUtils;
import com.model.Student;
import com.model.Teacher;

public class TestStudentTeacher {

 public static void main(String[] args) {

  Session session = HibernateUtils.getSessionFactory().openSession();
  Transaction tx = session.beginTransaction();
  try {

   Teacher teacher = new Teacher();
   teacher.setId("103021925");
   teacher.setName("Jason");

   Student student1 = new Student();
   student1.setId("9801232");
   student1.setName("王大明");

   Student student2 = new Student();
   student2.setId("9807201");
   student2.setName("張小東");

   Student student3 = new Student();
   student3.setId("9810235");
   student3.setName("陳又犬");

   teacher.setStudents(new HashSet());
   teacher.addStudent(student1);
   teacher.addStudent(student2);
   teacher.addStudent(student3);

   session.save(teacher);

   tx.commit();
  } catch (Exception e) {
   tx.rollback();
   e.printStackTrace();
  } finally {
   session.close();
   HibernateUtils.shutdown();
  }
 }
}

執行的console畫面,

Hibernate: select student_.id, student_.name as name6_ from student student_ where student_.id=?
Hibernate: select student_.id, student_.name as name6_ from student student_ where student_.id=?
Hibernate: select student_.id, student_.name as name6_ from student student_ where student_.id=?
Hibernate: insert into teacher (name, id) values (?, ?)
Hibernate: insert into student (name, id) values (?, ?)
Hibernate: insert into student (name, id) values (?, ?)
Hibernate: insert into student (name, id) values (?, ?)
Hibernate: update student set teacherId=? where id=?
Hibernate: update student set teacherId=? where id=?
Hibernate: update student set teacherId=? where id=?


可以看到一對多對於DB執行的效率不是很好,

會逐一更新每一筆多的資料,

接著是table內的資料:

table student














table teacher

沒有留言:

張貼留言