Hibernate的复合主键映射
生活随笔
收集整理的這篇文章主要介紹了
Hibernate的复合主键映射
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1>.學過hibernate的都知道用<id>來配置主鍵生成策略,顯然,它只能配置主鍵是單列的表,對于聯合主鍵的情況<id>就無能為力了。今天翻到個復合主鍵映射的資料,覺得還是有一定價值的,就寫了下來,以備后用。
??? 2>.hibernate處理復合主鍵映射是基于這樣一種做法:把目標類中所有主鍵關聯屬性抽出來,單獨寫成一個類(我暫且叫它主鍵類),目標類就只需持有主鍵類對象,而不必再包含各個主鍵屬性;在映射文件中使用<composite-id>標簽來配置主鍵對象并指出關聯屬性,普通屬性照常配置;hibernate只會創建一張表在,并且把主鍵設置為主鍵類各屬性的聯合主鍵,存儲和加載數據時,會自然的把關聯對象各屬性跟表中的主鍵字段對應起來。在這個操作過程中,它要求主鍵類必須是序列化的,并且要覆蓋equals方法,最好覆蓋hashCode方法。(我試驗過了,不覆蓋equals和hashCode,結果沒有出現任何問題,而且從輸出的sql語句看,也沒有影響數據庫操作,不知道它是否還有更深的含義?還希望高手給指點下)
??? 3>.例子。一個規模較大公司的部門表(hibernate_dept_compositePK),由所在區域(area),部門名(name),本部門人數(empCount),組建時間(birthday)等字段組成,我們使用所在區域和部門名做聯合主鍵: 1.目標類:Department.java public?class?Department {?
??/** 把主鍵關聯屬性抽象出來單獨寫成一個類 */?
??//private String area;?
??//private String name;?
??/**把主鍵類對象作為成員變量*/?
??private?DepartmentPK departmentPK;?
??private?int?empCount;?
??private?Date birthday;?
//??public String getArea() {?
//????return area;?
//??}?
//?
//??public void setArea(String area) {?
//????this.area = area;?
//??}?
//?
//??public String getName() {?
//????return name;?
//??}?
//?
//??public void setName(String name) {?
//????this.name = name;?
//??}?
????
??public?int?getEmpCount() {?
????return?empCount;?
??}?
??public?void?setEmpCount(int?empCount) {?
????this.empCount = empCount;?
??}?
??public?Date getBirthday() {?
????return?birthday;?
??}?
??public?void?setBirthday(Date birthday) {?
????this.birthday = birthday;?
??}?
??public?DepartmentPK getDepartmentPK() {?
????return?departmentPK;?
??}?
??public?void?setDepartmentPK(DepartmentPK departmentPK) {?
????this.departmentPK = departmentPK;?
??}?
} 2.主鍵類:DepartmentPK.java public?class?DepartmentPK?implements?Serializable {?
??private?static?final?long?serialVersionUID = -288002855915204255L;?
??private?String area;?
??private?String name;?
??/**?
????* 覆蓋hashCode方法(根據area和name判斷)?
????*/?
??//@Override?
??public?int?hashCode() {?
????final?int?prime = 31;?
????int?result = 1;?
????result = prime * result + ((area ==?null) ? 0 : area.hashCode());?
????result = prime * result + ((name ==?null) ? 0 : name.hashCode());?
????return?result;?
??}?
??/**?
????* 覆蓋equals(根據area和name判斷)?
????*/?
??@Override?
??public?boolean?equals(Object obj) {?
????if?(this?== obj)?
??????return?true;?
????if?(obj ==?null)?
??????return?false;?
????if?(getClass() != obj.getClass())?
??????return?false;?
????final?DepartmentPK other = (DepartmentPK) obj;?
????if?(area ==?null) {?
??????if?(other.area !=?null)?
????????return?false;?
????}?else?if?(!area.equals(other.area))?
??????return?false;?
????if?(name ==?null) {?
??????if?(other.name !=?null)?
????????return?false;?
????}?else?if?(!name.equals(other.name))?
??????return?false;?
????return?true;?
??}?
??public?String getArea() {?
????return?area;?
??}?
??public?void?setArea(String area) {?
????this.area = area;?
??}?
??public?String getName() {?
????return?name;?
??}?
??public?void?setName(String name) {?
????this.name = name;?
??}?
} 3.映射文件Department.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.yangfei.hibernate.compositePk.entity.Department"?table="hibernate_dept_compositePK">?
????<!--?聯合主鍵?-->?
????<!--?name指的是主鍵對象屬性?-->?
????<composite-id?name="departmentPK">?
??????<!--?這里是主鍵關聯屬性?-->?
??????<key-property?name="area"?/>?
??????<key-property?name="name"?/>?
????</composite-id>?
????<!--?其它屬性?-->?
????<property?name="empCount"?length="4"?/>?
????<property?name="birthday"?type="date"?/>?
??</class>?
</hibernate-mapping> 4.hibernate配置文件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="dialect">org.hibernate.dialect.Oracle9Dialect</property>?
????????????????<property?name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl10</property>?
????????????????<property?name="connection.username">scott</property>?
????????????????<property?name="connection.password">yf123</property>?
????????????????<property?name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>?
????????????????<property?name="hibernate.show_sql">true</property>?
????????????
??????????<mapping?resource="com/yangfei/hibernate/compositePk/entity/Department.hbm.xml"/>?
????????</session-factory>?
</hibernate-configuration> 5.測試類:DepartmentTest.java public?class?DepartmentTest?extends?TestCase {?
??/**?
????* 測試插入數據?
????*/?
??public?void?save() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????Department dept =?new?Department();?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
??????dept.setDepartmentPK(deptPK);?
??????dept.setEmpCount(100);?
??????dept.setBirthday(new?Date());?
??????session.save(dept);?
??????t.commit();?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
??/**?
????* 測試加載數據?
????*/?
??public?void?load() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
??????Department dept=(Department)session.load(Department.class, deptPK);?
??????System.out.println(dept.getDepartmentPK().getArea()+","+dept.getDepartmentPK().getName()+","+dept.getEmpCount()+","+dept.getBirthday());?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
????
??/**?
????* 測試修改數據?
????*/?
??public?void?update() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
??????Department emp=(Department)session.load(Department.class, deptPK);?
??????System.out.println(emp.getDepartmentPK().getArea()+","+emp.getDepartmentPK().getName()+","+emp.getEmpCount()+","+emp.getBirthday());?
??????emp.setEmpCount(100);?
??????session.saveOrUpdate(emp);?
????????
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK2 =?new?DepartmentPK();?
??????deptPK2.setArea("北京");?
??????deptPK2.setName("研發部");?
??????Department dept=(Department)session.load(Department.class, deptPK2);?
??????System.out.println(dept.getDepartmentPK().getArea()+","+dept.getDepartmentPK().getName()+","+dept.getEmpCount()+","+dept.getBirthday());?
??????t.commit();?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
????
??/**?
????* 測試刪除數據?
????*/?
??public?void?delete() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
????????
??????Department dept=(Department)session.load(Department.class, deptPK);?
??????session.delete(dept);?
??????t.commit();?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
} 4.一般來說,復合主鍵映射用起來是很復雜的,無論是開發時還是升級時。所以,人們往往寧愿選擇增加個主鍵字段,也不盡量不采用它。
? ? ?本文轉自NightWolves 51CTO博客,原文鏈接:http://blog.51cto.com/yangfei520/310555,如需轉載請自行聯系原作者
??? 2>.hibernate處理復合主鍵映射是基于這樣一種做法:把目標類中所有主鍵關聯屬性抽出來,單獨寫成一個類(我暫且叫它主鍵類),目標類就只需持有主鍵類對象,而不必再包含各個主鍵屬性;在映射文件中使用<composite-id>標簽來配置主鍵對象并指出關聯屬性,普通屬性照常配置;hibernate只會創建一張表在,并且把主鍵設置為主鍵類各屬性的聯合主鍵,存儲和加載數據時,會自然的把關聯對象各屬性跟表中的主鍵字段對應起來。在這個操作過程中,它要求主鍵類必須是序列化的,并且要覆蓋equals方法,最好覆蓋hashCode方法。(我試驗過了,不覆蓋equals和hashCode,結果沒有出現任何問題,而且從輸出的sql語句看,也沒有影響數據庫操作,不知道它是否還有更深的含義?還希望高手給指點下)
??? 3>.例子。一個規模較大公司的部門表(hibernate_dept_compositePK),由所在區域(area),部門名(name),本部門人數(empCount),組建時間(birthday)等字段組成,我們使用所在區域和部門名做聯合主鍵: 1.目標類:Department.java public?class?Department {?
??/** 把主鍵關聯屬性抽象出來單獨寫成一個類 */?
??//private String area;?
??//private String name;?
??/**把主鍵類對象作為成員變量*/?
??private?DepartmentPK departmentPK;?
??private?int?empCount;?
??private?Date birthday;?
//??public String getArea() {?
//????return area;?
//??}?
//?
//??public void setArea(String area) {?
//????this.area = area;?
//??}?
//?
//??public String getName() {?
//????return name;?
//??}?
//?
//??public void setName(String name) {?
//????this.name = name;?
//??}?
????
??public?int?getEmpCount() {?
????return?empCount;?
??}?
??public?void?setEmpCount(int?empCount) {?
????this.empCount = empCount;?
??}?
??public?Date getBirthday() {?
????return?birthday;?
??}?
??public?void?setBirthday(Date birthday) {?
????this.birthday = birthday;?
??}?
??public?DepartmentPK getDepartmentPK() {?
????return?departmentPK;?
??}?
??public?void?setDepartmentPK(DepartmentPK departmentPK) {?
????this.departmentPK = departmentPK;?
??}?
} 2.主鍵類:DepartmentPK.java public?class?DepartmentPK?implements?Serializable {?
??private?static?final?long?serialVersionUID = -288002855915204255L;?
??private?String area;?
??private?String name;?
??/**?
????* 覆蓋hashCode方法(根據area和name判斷)?
????*/?
??//@Override?
??public?int?hashCode() {?
????final?int?prime = 31;?
????int?result = 1;?
????result = prime * result + ((area ==?null) ? 0 : area.hashCode());?
????result = prime * result + ((name ==?null) ? 0 : name.hashCode());?
????return?result;?
??}?
??/**?
????* 覆蓋equals(根據area和name判斷)?
????*/?
??@Override?
??public?boolean?equals(Object obj) {?
????if?(this?== obj)?
??????return?true;?
????if?(obj ==?null)?
??????return?false;?
????if?(getClass() != obj.getClass())?
??????return?false;?
????final?DepartmentPK other = (DepartmentPK) obj;?
????if?(area ==?null) {?
??????if?(other.area !=?null)?
????????return?false;?
????}?else?if?(!area.equals(other.area))?
??????return?false;?
????if?(name ==?null) {?
??????if?(other.name !=?null)?
????????return?false;?
????}?else?if?(!name.equals(other.name))?
??????return?false;?
????return?true;?
??}?
??public?String getArea() {?
????return?area;?
??}?
??public?void?setArea(String area) {?
????this.area = area;?
??}?
??public?String getName() {?
????return?name;?
??}?
??public?void?setName(String name) {?
????this.name = name;?
??}?
} 3.映射文件Department.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.yangfei.hibernate.compositePk.entity.Department"?table="hibernate_dept_compositePK">?
????<!--?聯合主鍵?-->?
????<!--?name指的是主鍵對象屬性?-->?
????<composite-id?name="departmentPK">?
??????<!--?這里是主鍵關聯屬性?-->?
??????<key-property?name="area"?/>?
??????<key-property?name="name"?/>?
????</composite-id>?
????<!--?其它屬性?-->?
????<property?name="empCount"?length="4"?/>?
????<property?name="birthday"?type="date"?/>?
??</class>?
</hibernate-mapping> 4.hibernate配置文件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="dialect">org.hibernate.dialect.Oracle9Dialect</property>?
????????????????<property?name="connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl10</property>?
????????????????<property?name="connection.username">scott</property>?
????????????????<property?name="connection.password">yf123</property>?
????????????????<property?name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property>?
????????????????<property?name="hibernate.show_sql">true</property>?
????????????
??????????<mapping?resource="com/yangfei/hibernate/compositePk/entity/Department.hbm.xml"/>?
????????</session-factory>?
</hibernate-configuration> 5.測試類:DepartmentTest.java public?class?DepartmentTest?extends?TestCase {?
??/**?
????* 測試插入數據?
????*/?
??public?void?save() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????Department dept =?new?Department();?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
??????dept.setDepartmentPK(deptPK);?
??????dept.setEmpCount(100);?
??????dept.setBirthday(new?Date());?
??????session.save(dept);?
??????t.commit();?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
??/**?
????* 測試加載數據?
????*/?
??public?void?load() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
??????Department dept=(Department)session.load(Department.class, deptPK);?
??????System.out.println(dept.getDepartmentPK().getArea()+","+dept.getDepartmentPK().getName()+","+dept.getEmpCount()+","+dept.getBirthday());?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
????
??/**?
????* 測試修改數據?
????*/?
??public?void?update() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
??????Department emp=(Department)session.load(Department.class, deptPK);?
??????System.out.println(emp.getDepartmentPK().getArea()+","+emp.getDepartmentPK().getName()+","+emp.getEmpCount()+","+emp.getBirthday());?
??????emp.setEmpCount(100);?
??????session.saveOrUpdate(emp);?
????????
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK2 =?new?DepartmentPK();?
??????deptPK2.setArea("北京");?
??????deptPK2.setName("研發部");?
??????Department dept=(Department)session.load(Department.class, deptPK2);?
??????System.out.println(dept.getDepartmentPK().getArea()+","+dept.getDepartmentPK().getName()+","+dept.getEmpCount()+","+dept.getBirthday());?
??????t.commit();?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
????
??/**?
????* 測試刪除數據?
????*/?
??public?void?delete() {?
????Session session = HibernateUtils.getSession();?
????Transaction t = session.beginTransaction();?
????try?{?
??????/** 生成主鍵對象 */?
??????DepartmentPK deptPK =?new?DepartmentPK();?
??????deptPK.setArea("北京");?
??????deptPK.setName("研發部");?
????????
??????Department dept=(Department)session.load(Department.class, deptPK);?
??????session.delete(dept);?
??????t.commit();?
????}?catch?(HibernateException e) {?
??????e.printStackTrace();?
??????t.rollback();?
????}?finally?{?
??????HibernateUtils.closeSession(session);?
????}?
??}?
} 4.一般來說,復合主鍵映射用起來是很復雜的,無論是開發時還是升級時。所以,人們往往寧愿選擇增加個主鍵字段,也不盡量不采用它。
? ? ?本文轉自NightWolves 51CTO博客,原文鏈接:http://blog.51cto.com/yangfei520/310555,如需轉載請自行聯系原作者
總結
以上是生活随笔為你收集整理的Hibernate的复合主键映射的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux学习之CentOS(五)--让
- 下一篇: 关于Oracle undostat中的2