隨筆 - 117  文章 - 72  trackbacks - 0

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

          常用鏈接

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

          訂閱

          訂閱

          留言簿(7)

          隨筆分類(130)

          隨筆檔案(123)

          搜索

          •  

          積分與排名

          • 積分 - 155954
          • 排名 - 389

          最新評論

          [標題]:[原]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{
              ......
          }

          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:
          ......

          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;
              
              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;
              }
          }


          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" />
              </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);
              }
          }


          index.jsp:查詢Student及其課程列表
          <%@ 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<Student> students = null;
                  DAO dao = new DAOBean();
                  dao.insert();
                  students = dao.selectAll("from Student");
                      
                  Iterator<Student> it = students.iterator();
                  while(it.hasNext()){
                      Student student = it.next();
                      int id = student.getId();
                      String name = student.getName();
                      out.println("id:" + id + "<br />");
                      out.println("name:" + name + "<br />");
                      out.println("courses:<br />");
                      
                      Set<Course> cards = student.getCourses();
                      Iterator<Course> itc = cards.iterator();
                      while(itc.hasNext()){
                          Course course = itc.next();
                          int courseId = course.getId();
                          String courseName = course.getName();
                          out.println("&nbsp;&nbsp;&nbsp; id:" + courseId + "<br />");
                          out.println("&nbsp;&nbsp;&nbsp; name:" + courseName + "<br />");
                      }
                      out.println("<hr/>");
                  }
              %>

            </body>
          </html>

          5、運行結果
          控制臺顯示:
          ......
          Hibernate: insert into db.course (name, id) values (?, ?)
          Hibernate: insert into db.course (name, id) values (?, ?)
          Hibernate: insert into db.course (name, id) values (?, ?)
          Hibernate: insert into db.student (name, id) values (?, ?)
          Hibernate: insert into db.student (name, id) values (?, ?)
          Hibernate: insert into student_course (studentid, courseid) values (?, ?)
          Hibernate: insert into student_course (studentid, courseid) values (?, ?)
          Hibernate: insert into student_course (studentid, courseid) values (?, ?)
          Hibernate: insert into student_course (studentid, courseid) values (?, ?)
          ......

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

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

          posted on 2009-06-19 22:43 天堂露珠 閱讀(1008) 評論(1)  編輯  收藏 所屬分類: Hibernate

          FeedBack:
          # re: [原]Hibernate多對多(單向) 2011-08-09 15:40 
          中間表不用做映射,那student_course的表哪里來啊,   回復  更多評論
            
          主站蜘蛛池模板: 库尔勒市| 额尔古纳市| 桃园市| 惠水县| 石城县| 霞浦县| 兰坪| 砚山县| 会泽县| 个旧市| 达拉特旗| 通化县| 通化市| 武定县| 响水县| 淳化县| 朝阳市| 天峨县| 岳西县| 连州市| 连江县| 岳池县| 禹州市| 侯马市| 开江县| 绥阳县| 景东| 察隅县| 桂平市| 迭部县| 昆山市| 河曲县| 海安县| 土默特右旗| 天峨县| 黔西县| 资兴市| 镇赉县| 平阳县| 新民市| 永寿县|