隨筆 - 117  文章 - 72  trackbacks - 0

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

          常用鏈接

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

          訂閱

          訂閱

          留言簿(7)

          隨筆分類(130)

          隨筆檔案(123)

          搜索

          •  

          積分與排名

          • 積分 - 155530
          • 排名 - 390

          最新評論

          [標題]:[原]Hibernate繼承映射-具體類映射為數據庫表
          [時間]:2009-6-21
          [摘要]:每一個具體子類映射成單個數據庫表,而抽象基類不參與映射。優點:數據操作實現簡單,每個表中都包含自己所需要的具體子類的所有信息,減少了多表關聯操作時的性能消耗。缺點:類的修改會導致相對應的表及其子類所對應表的更改。不支持多態查詢。應用:適合在類層次結構上有一定數量的抽象類的情況下使用。
          [關鍵字]:Hibernate,ORM,關聯,繼承,持久化,映射,Abstract
          [環境]:MyEclipse7,Hibernate3.2,MySQL5.1
          [作者]:Winty (wintys@gmail.com) http://www.aygfsteel.com/wintys

          [正文]:
              每一個具體子類映射成單個數據庫表,而抽象基類不參與映射。
          優點:數據操作實現簡單,每個表中都包含自己所需要的具體子類的所有信息,減少了多表關聯操作時的性能消耗。

          缺點:
              類的修改會導致相對應的表及其子類所對應表的更改。不支持多態查詢。

          應用:
              適合在類層次結構上有一定數量的抽象類的情況下使用。
              
              例:學校管理系統中的實體關系:

              【圖:department.jpg】
          1、概述
          a.實體類
          public class Department {
              ......
              //由于Person類沒有被映射,所以無法實現Department到Person的關聯
              ......
          }

          public abstract class Person {
              ......
              private Department department;
              ......
          }

          public class Student extends Person {
              ......
          }

          public class Teacher extends Person {
              ......
          }

          b.數據庫表
              具體子類Student和Teacher分別映射成一張表,各自的表中都包含從父類繼承來的屬性。

          c.配置文件
          由于Person類沒有被映射,所以無法映射Person到Department的關聯,只能由子類Student和Teacher實現映射。

          Student.hbm.xml:
          包含父類屬性的映射
          ......
          <many-to-one name="department"
                      unique="true"
                      column="dept"
                      class="wintys.hibernate.inheritance.concrete.Department"/>
          ......


          Teacher.hbm.xml:
          包含父類屬性的映射
          ......
          <many-to-one name="department"
                      unique="true"
                      column="dept"
                      class="wintys.hibernate.inheritance.concrete.Department"/>
          ......

          2、實體類:
          Department.java:
          package wintys.hibernate.inheritance.concrete;

          /**
           *
           * @version 2009-06-20
           * @author Winty (wintys@gmail.com)
           *
           */
          public class Department {
              private Integer id;
              private String name;
              private String desc;
              
              
              public Department(){
                  
              }
              
              public Department(String name , String desc){
                  this.name = name;
                  this.desc = desc;
              }
              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 String getDesc() {
                  return desc;
              }
              public void setDesc(String desc) {
                  this.desc = desc;
              }
          }


          Person.java:
          package wintys.hibernate.inheritance.concrete;

          /**
           *
           * @version 2009-06-20
           * @author Winty (wintys@gmail.com)
           *
           */
          public abstract class Person {
              private Integer id;
              private String name;
              private Department department;
              
              public Person(){
              }
              
              public Person(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 Department getDepartment() {
                  return department;
              }
              public void setDepartment(Department department) {
                  this.department = department;
              }
          }


          Student.java:
          package wintys.hibernate.inheritance.concrete;

          /**
           *
           * @version 2009-06-20
           * @author Winty (wintys@gmail.com)
           *
           */
          public class Student extends Person {
              private String studentMajor;
              
              public Student(){
                  
              }
              
              public Student(String name , String major){
                  super(name);
                  this.studentMajor = major;
              }

              public String getStudentMajor() {
                  return studentMajor;
              }

              public void setStudentMajor(String studentMajor) {
                  this.studentMajor = studentMajor;
              }
          }


          Teacher.java:
          package wintys.hibernate.inheritance.concrete;

          /**
           *
           * @version 2009-06-20
           * @author Winty (wintys@gmail.com)
           *
           */
          public class Teacher extends Person {
              private Float teacherSalary;

              public Teacher(){
                  
              }
              
              public Teacher(String name , Float teacherSalary){
                  super(name);
                  this.teacherSalary = teacherSalary;
              }
              
              public Float getTeacherSalary() {
                  return teacherSalary;
              }

              public void setTeacherSalary(Float teacherSalary) {
                  this.teacherSalary = teacherSalary;
              }
          }



          3、數據庫表:

          【圖:concret_db.jpg】
          db.sql:
          -- Author:Winty (wintys@gmail.com)
          -- Date:2009-06-20
          -- http://www.aygfsteel.com/wintys

          -- Department
          CREATE TABLE mydepartment(
              id      INT(4) NOT NULL,
              name    VARCHAR(100),
              descs  VARCHAR(100),
              PRIMARY KEY(id)
          );

          -- Student
          CREATE TABLE mystudent(
              id              INT(4) NOT NULL,
              name            VARCHAR(100),
              dept            INT(4),-- 從Person繼承了與Department的關聯
              studentMajor    VARCHAR(100),
              PRIMARY KEY(id),
              CONSTRAINT FK_dept_s FOREIGN KEY(dept) REFERENCES mydepartment(id)
          );

          -- Teacher
          CREATE TABLE myteacher(
              id              INT(4) NOT NULL,
              name            VARCHAR(100),
              dept            INT(4), -- 從Person繼承了與Department的關聯
              teacherSalary   FLOAT(7,2),
              PRIMARY KEY(id),
              CONSTRAINT FK_dept_t FOREIGN KEY(dept) REFERENCES mydepartment(id)
          );

          4、映射文件:

          【圖:concrete_mapping.jpg】
          Department.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.inheritance.concrete.Department" table="mydepartment" catalog="db">
                  <id name="id" type="int">
                      <column name="id" not-null="true"/>
                      <generator class="increment" />
                  </id>
                  <property name="name" />
                  <property name="desc" type="string" column="descs"/>
              </class>
          </hibernate-mapping>


          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.inheritance.concrete.Student" table="mystudent" catalog="db">
                  <id name="id" type="int">
                      <column name="id" not-null="true"/>
                      <generator class="increment" />
                  </id>
                  <property name="name" />
                  <property name="studentMajor" />
                  
                  <many-to-one name="department"
                              unique="true"
                              column="dept"
                              class="wintys.hibernate.inheritance.concrete.Department"/>
              </class>
          </hibernate-mapping>


          Teacher.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.inheritance.concrete.Teacher" table="myteacher" catalog="db">
                  <id name="id" type="int">
                      <column name="id" not-null="true"/>
                      <generator class="increment" />
                  </id>
                  <property name="name" />
                  <property name="teacherSalary" type="float"/>
                  
                  <many-to-one name="department"
                              unique="true"
                              column="dept"
                              class="wintys.hibernate.inheritance.concrete.Department"/>
              </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/inheritance/concrete/Department.hbm.xml" />
              <mapping
                  resource="wintys/hibernate/inheritance/concrete/Student.hbm.xml" />
              <mapping
                  resource="wintys/hibernate/inheritance/concrete/Teacher.hbm.xml" />

          </session-factory>

          </hibernate-configuration>


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

          import java.util.List;

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


          DAOBean.java:
          package wintys.hibernate.inheritance.concrete;

          import java.util.List;

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

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

              @Override
              public void insert() {
                  Transaction tc = null;
                  try{
                      Department dept = new Department("college of math" , "the top 3 college");
                      Person p1,p2;
                      p1 = new Student("Sam" , "Math");
                      p1.setDepartment(dept);
                      p2 = new Teacher("Martin" , new Float(15000f));
                      p2.setDepartment(dept);
                      
                      Session session = HibernateUtil.getSession();
                      tc = session.beginTransaction();
                                  
                      session.save(dept);
                      //多態保存
                      session.save(p1);
                      session.save(p2);
                  
                      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")
              @Override
              public <T> List<T> select(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.inheritance.concrete;

          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 {    
                  threadLocal = new ThreadLocal<Session>();
              }
              
              private HibernateUtil(){    
              }
              
              //Should be call only once.
              //設置Hibernate.cfg.xml的位置
              public static void setConfigFile(String hibernate_cfg_xml){
                  try{
                      factory = new Configuration()
                              .configure(hibernate_cfg_xml)
                              .buildSessionFactory();
                  }catch(HibernateException e){
                      System.err.println(e.getMessage());
                  }
              }
              
              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);
              }
          }



          Test.java:
          package wintys.hibernate.inheritance.concrete;

          import java.util.Iterator;
          import java.util.List;

          public class Test {

              public static void main(String[] args) {
                  String config = "wintys/hibernate/inheritance/concrete/hibernate.cfg.xml";
                  HibernateUtil.setConfigFile(config);
                  
                  DAO dao = new DAOBean();
                  dao.insert();
                  //不支持多態查詢
                  //Error:Person is not mapped
                  //List<Person> ps = dao.select("from Person");
                  //System.out.println(printStudentOrTeacher(ps));
                  
                  List<Student> students = dao.select("from Student");
                  System.out.println(printStudentOrTeacher(students));
                  
                  List<Student> teachers = dao.select("from Teacher");
                  System.out.println(printStudentOrTeacher(teachers));        
              }
              
              public static String printStudentOrTeacher(List<? extends Person> students){
                  String str = "";
                  Iterator<? extends Person> it = students.iterator();
                  while(it.hasNext()){
                      Person person = it.next();
                      int id = person.getId();
                      String name = person.getName();
                      Department dept = person.getDepartment();
                          
                      int deptId = dept.getId();
                      String deptName = dept.getName();
                      String deptDesc = dept.getDesc();
                      
                      str += "id:" +id + ""n";
                      str += "name:" + name + ""n";
                      if(person instanceof Student)
                          str += "major:"  + ((Student) person).getStudentMajor() + ""n";
                      if(person instanceof Teacher)
                          str += "salary:" + ((Teacher) person).getTeacherSalary().toString() + ""n";
                      str += "dept:" + ""n";
                      str += "  deptId:" + deptId + ""n";
                      str += "  deptName:" + deptName + ""n";
                      str += "  deptDesc:" + deptDesc + ""n";    
                      str += ""n";
                  }
                  return str;
              }
          }


          5、運行結果
          控制臺顯示:
          ......
          Hibernate: select max(id) from mydepartment
          Hibernate: select max(id) from mystudent
          Hibernate: select max(id) from myteacher
          Hibernate: insert into db.mydepartment (name, descs, id) values (?, ?, ?)
          Hibernate: insert into db.mystudent (name, studentMajor, dept, id) values (?, ?, ?, ?)
          Hibernate: insert into db.myteacher (name, teacherSalary, dept, id) values (?, ?, ?, ?)
          Hibernate: select student0_.id as id1_, student0_.name as name1_, student0_.studentMajor as studentM3_1_, student0_.dept as dept1_ from db.mystudent student0_
          Hibernate: select department0_.id as id0_0_, department0_.name as name0_0_, department0_.descs as descs0_0_ from db.mydepartment department0_ where department0_.id=?
          id:1
          name:Sam
          major:Math
          dept:
            deptId:1
            deptName:college of math
            deptDesc:the top 3 college


          Hibernate: select teacher0_.id as id2_, teacher0_.name as name2_, teacher0_.teacherSalary as teacherS3_2_, teacher0_.dept as dept2_ from db.myteacher teacher0_
          id:1
          name:Martin
          salary:15000.0
          dept:
            deptId:1
            deptName:college of math
            deptDesc:the top 3 college

          [參考資料]:
          《J2EE項目實訓--Hibernate框架技術》-楊少波 : 清華大學出版社
          原創作品,轉載請注明出處。
          作者:Winty (wintys@gmail.com)
          博客:http://www.aygfsteel.com/wintys

          posted on 2009-06-21 13:05 天堂露珠 閱讀(707) 評論(0)  編輯  收藏 所屬分類: Hibernate
          主站蜘蛛池模板: 玉树县| 叶城县| 利川市| 江陵县| 鄂温| 康平县| 开封市| 顺昌县| 敦化市| 安丘市| 明光市| 孙吴县| 曲麻莱县| 门头沟区| 谢通门县| 文登市| 富锦市| 丹寨县| 明溪县| 壤塘县| 怀仁县| 邵阳县| 尖扎县| 大庆市| 四川省| 壤塘县| 枣强县| 梨树县| 连云港市| 北碚区| 古丈县| 永寿县| 高邑县| 兴城市| 扎赉特旗| 阿尔山市| 河间市| 巫山县| 凭祥市| 交城县| 宣威市|