隨筆 - 117  文章 - 72  trackbacks - 0

          聲明:原創作品(標有[原]字樣)轉載時請注明出處,謝謝。

          常用鏈接

          常用設置
          常用軟件
          常用命令
           

          訂閱

          訂閱

          留言簿(7)

          隨筆分類(130)

          隨筆檔案(123)

          搜索

          •  

          積分與排名

          • 積分 - 155531
          • 排名 - 390

          最新評論

          [標題]:[原]Hibernate多對多(雙向)
          [時間]:2009-6-19
          [摘要]:Hibernate雙向多對多關聯。如:一個學生對應多門課程,一門課程也對應多名學生。
          [關鍵字]:Hibernate,ORM,關聯,多對多,持久化,雙向,映射
          [環境]:MyEclipse7,Hibernate3.2,MySQL5.1
          [作者]:Winty (wintys@gmail.com) http://www.aygfsteel.com/wintys

          [正文]:
              Hibernate單向多對多關聯。如:一個學生對應多門課程,一門課程也對應多名學生。本例單向關聯,只考慮學生到課程的一對多關聯。
          1、概述
          a.實體類
          public class Student{
              ......
              private Set<Course> courses;
              ......
          }

          public class Course{
              ......
              private Set<Student> students;
              ......
          }

          b.數據庫表
              Student與Course各對應一張數據庫表,再建一張關聯表student_course (studentid,courseid),保存多對多關聯。其中,student_course表的主鍵為studentid與courseid的聯合。

          c.配置文件
          Student.hbm.xml:
          ......
          <set name="courses" table="student_course" cascade="all">
              <key column="studentid" />
              <many-to-many column="courseid" class="wintys.hibernate.manytomany.Course"/>
          </set>
          ......

          Course.hbm.xml:
          ......
          <set name="students" table="student_course" inverse="true" >
              <key column="courseid"/>
              <many-to-many column="studentid" class="wintys.hibernate.manytomany.Student" />
          </set>
          ......

          2、實體類:
          Student.java:
          package wintys.hibernate.manytomany;

          import java.util.Set;

          /**
           * @version 2009-06-19
           * @author Winty (wintys@gmail.com)
           *
           */
          public class Student {
              private Integer id;
              private String name;
              private Set<Course> courses;
              
              public Student(){
              }
              
              public Student(String name){
                  this.name = name;
              }
                               
              public Integer getId() {
                  return id;
              }
              public void setId(Integer id) {
                  this.id = id;
              }
              public String getName() {
                  return name;
              }
              public void setName(String name) {
                  this.name = name;
              }
              public Set<Course> getCourses() {
                  return courses;
              }
              public void setCourses(Set<Course> courses) {
                  this.courses = courses;
              }
          }


          Course.java:
          package wintys.hibernate.manytomany;

          import java.util.Set;

          /**
           * @version 2009-06-19
           * @author Winty (wintys@gmail.com)
           *
           */
          public class Course {
              private Integer id;
              private String name;
              //實現雙向"多對多"關聯
              private Set<Student> students;
              
              public Course(){
              }
              
              public Course(String name){
                  this.name = name;
              }
              
              public Integer getId() {
                  return id;
              }
              public void setId(Integer id) {
                  this.id = id;
              }
              public String getName() {
                  return name;
              }
              public void setName(String name) {
                  this.name = name;
              }

              public Set<Student> getStudents() {
                  return students;
              }

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


          3、數據庫表:
          db.sql:
          CREATE TABLE student(
              id int(4) NOT NULL UNIQUE,
              name varchar(100),
              PRIMARY KEY(id)
          );

          CREATE TABLE course(
              id int(4) NOT NULL UNIQUE,
              name varchar(100),
              PRIMARY KEY(id)
          );

          -- 關聯表
          CREATE TABLE student_course(
              studentid int(4) NOT NULL,
              courseid int(4) NOT NULL,
              PRIMARY KEY(studentid,courseid),
              CONSTRAINT FK_studentid FOREIGN KEY(studentid) REFERENCES student(id),
              CONSTRAINT FK_courseid  FOREIGN KEY(courseid) REFERENCES course(id)
          );

          4、映射文件:
          Student.hbm.xml:
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
          <!--
              Mapping file autogenerated by MyEclipse Persistence Tools
          -->

          <hibernate-mapping>
              <class name="wintys.hibernate.manytomany.Student" table="student" catalog="db">
                  <id name="id" type="int">
                      <column name="id" not-null="true"/>
                      <generator class="increment" />
                  </id>
                  <property name="name" />
                  
                  <set name="courses" table="student_course" cascade="all">
                      <key column="studentid" />
                      <many-to-many column="courseid" class="wintys.hibernate.manytomany.Course"/>
                  </set>
              </class>
          </hibernate-mapping>


          Course.hbm.xml:
          <?xml version="1.0" encoding="UTF-8"?>
          <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
          <!--
              Mapping file autogenerated by MyEclipse Persistence Tools
          -->

          <hibernate-mapping>
              <class name="wintys.hibernate.manytomany.Course" table="course" catalog="db">
                  <id name="id" type="int">
                      <column name="id" not-null="true"/>
                      <generator class="increment" />
                  </id>
                  <property name="name" />
                  <!-- 實現雙向"多對多"關聯 -->    
                  <set name="students" table="student_course" inverse="true" >
                      <key column="courseid"/>
                      <many-to-many column="studentid" class="wintys.hibernate.manytomany.Student" />
                  </set>
              </class>
          </hibernate-mapping>



          hibernate.cfg.xml:
          <?xml version='1.0' encoding='UTF-8'?>
          <!DOCTYPE hibernate-configuration PUBLIC
                    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                    "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

          <!-- Generated by MyEclipse Hibernate Tools.                   -->
          <hibernate-configuration>

          <session-factory>
              <property name="connection.username">root</property>
              <property name="connection.url">
                  jdbc:mysql://localhost:3306/db?useUnicode=true&amp;characterEncoding=utf-8
              </property>
              <property name="dialect">
                  org.hibernate.dialect.MySQLDialect
              </property>
              <property name="myeclipse.connection.profile">MySQLDriver</property>
              <property name="connection.password">root</property>
              <property name="connection.driver_class">
                  com.mysql.jdbc.Driver
              </property>
              <property name="show_sql">true</property>
              <mapping resource="wintys/hibernate/manytomany/Student.hbm.xml" />
              <mapping resource="wintys/hibernate/manytomany/Course.hbm.xml" />

          </session-factory>

          </hibernate-configuration>


          4、使用測試:
          DAO.java:
          package wintys.hibernate.manytomany;

          import java.util.List;

          public interface DAO {
              public void insert();
              public <T> List<T> selectAll(String hql);
          }

          DAOBean.java:
          package wintys.hibernate.manytomany;

          import java.util.List;
          import java.util.HashSet;
          import java.util.Set;

          import org.hibernate.HibernateException;
          import org.hibernate.Query;
          import org.hibernate.Session;
          import org.hibernate.Transaction;

          /**
           * @version 2009-06-19
           * @author Winty (wintys@gmail.com)
           *
           */
          public class DAOBean implements DAO {

              public void insert() {
                  Transaction tc = null;
                  try{
                      Course c1,c2,c3;
                      Student s1,s2;
                      Set<Course> cs1 , cs2;
                      
                      c1 = new Course("Course 1");
                      c2 = new Course("Course 2");
                      c3 = new Course("Course 3");
                      s1 = new Student("Student 1");
                      s2 = new Student("Student 2");
                      cs1 = new HashSet<Course>();
                      cs2 = new HashSet<Course>();
                      
                      //c2為兩個集合共有
                      cs1.add(c1);
                      cs1.add(c2);
                      cs2.add(c2);
                      cs2.add(c3);
                      
                      s1.setCourses(cs1);
                      s2.setCourses(cs2);         
                      
                      Session session = HibernateUtil.getSession();
                      tc = session.beginTransaction();
                                  
                      /*
                      在Student.hbm.xml中設置了cascade="all",就不需要手動保存c1/c2/c3
                      session.save(c1);
                      session.save(c2);
                      session.save(c3);
                      */
                      session.save(s1);
                      session.save(s2);
                  
                      tc.commit();
                  }catch(HibernateException e){
                      try{
                          if(tc != null)
                              tc.rollback();
                      }catch(Exception ex){
                          System.err.println(ex.getMessage());
                      }
                      System.err.println(e.getMessage());
                  }finally{
                      HibernateUtil.closeSession();           
                  }       
              }

              @SuppressWarnings("unchecked")
              public <T> List<T> selectAll(String hql) {
                  List<T> items = null;
                  Transaction tc = null;
                  try{
                      Session session = HibernateUtil.getSession();
                      tc = session.beginTransaction();
                                  
                      Query query = session.createQuery(hql);
                      items = query.list();
                      
                      tc.commit();
                  }catch(HibernateException e){
                      try{
                          if(tc != null){
                              tc.rollback();
                              items = null;
                          }
                      }catch(Exception ex){
                          System.err.println(ex.getMessage());
                      }
                      System.err.println(e.getMessage());
                  }finally{
                      //HibernateUtil.closeSession();         
                  }
                  
                  return items;
              }
          }


          HibernateUtil.java:
          package wintys.hibernate.manytomany;

          import org.hibernate.HibernateException;
          import org.hibernate.Session;
          import org.hibernate.SessionFactory;
          import org.hibernate.cfg.Configuration;

          /**
           * Hibernate Session管理
           * @author Winty
           */
          public class HibernateUtil {
              private static SessionFactory factory = null;
              private static ThreadLocal<Session> threadLocal;
                  
              static {
                  try{
                      factory = new Configuration()
                              .configure()
                              .buildSessionFactory();
                  }catch(HibernateException e){
                      System.err.println(e.getMessage());
                  }
                  
                  threadLocal = new ThreadLocal<Session>();
              }
              
              private HibernateUtil(){    
              }
              
              public static Session getSession()throws HibernateException{
                  Session session = threadLocal.get();
                  if(session == null){
                      session = factory.openSession();
                      threadLocal.set(session);
                  }
                  
                  return session;
              }
              
              public static void closeSession()throws HibernateException{
                  Session session = threadLocal.get();
                  if(session != null){
                      session.close();
                  }
                  threadLocal.set(null);
              }
          }


          course.jsp:查詢Course及其學生列表
          <%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>
          <%@ page import="wintys.hibernate.manytomany.*"%>
          <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
          <html>
            <head>
              <title>My JSP 'index.jsp' starting page</title>
            </head>
           
            <body>
              <%
                  List<Course> courses = null;
                  DAO dao = new DAOBean();
                  //dao.insert();
                  courses = dao.selectAll("from Course");
                      
                  Iterator<Course> it = courses.iterator();
                  while(it.hasNext()){
                      Course course = it.next();
                      int id = course.getId();
                      String name = course.getName();
                      out.println("id:" + id + "<br />");
                      out.println("name:" + name + "<br />");
                      out.println("students:<br />");
                      
                      Set<Student> students = course.getStudents();
                      Iterator<Student> itc = students.iterator();
                      while(itc.hasNext()){
                          Student student = itc.next();
                          int studentId = student.getId();
                          String studentName = student.getName();
                          out.println("&nbsp;&nbsp;&nbsp; id:" + studentId + "<br />");
                          out.println("&nbsp;&nbsp;&nbsp; name:" + studentName + "<br />");
                      }
                      out.println("<hr/>");
                  }
              %>

            </body>
          </html>


          5、運行結果

          Web頁面顯示:
          id:1
          name:Course 1
          students:
              id:1
              name:Student 1
          --------------------------------------------------------------------------------
          id:2
          name:Course 2
          students:
              id:2
              name:Student 2
              id:1
              name:Student 1
          --------------------------------------------------------------------------------
          id:3
          name:Course 3
          students:
              id:2
              name:Student 2
          --------------------------------------------------------------------------------


          [參考資料]:
          Hibernate 多對多雙向關聯-熔巖 : http://lavasoft.blog.51cto.com/62575/39344
          原創作品,轉載請注明出處。
          作者:Winty (wintys@gmail.com)
          博客:http://www.aygfsteel.com/wintys

          posted on 2009-06-19 22:50 天堂露珠 閱讀(398) 評論(0)  編輯  收藏 所屬分類: Hibernate
          主站蜘蛛池模板: 尼玛县| 泰顺县| 孟村| 青龙| 方正县| 无棣县| 武宣县| 株洲市| 桐柏县| 霍山县| 始兴县| 年辖:市辖区| 秦皇岛市| 长子县| 鹤峰县| 苗栗市| 十堰市| 边坝县| 尤溪县| 临高县| 达日县| 依兰县| 鸡西市| 合肥市| 泰顺县| 万年县| 长沙县| 泰安市| 汉阴县| 彝良县| 沁源县| 阿坝| 巩留县| 叶城县| 泽普县| 河池市| 诸暨市| 屏东市| 华容县| 彰武县| 剑阁县|