標籤:style blog http ar io color os 使用 sp
上篇文章討論了繼承映射,它是物件模型中最主要的特性,對於繼承映射它的主要區分是欄位類型的不同,所以在產生表結構時須要有新列來標識資料的類型,能夠使用<subclass>標籤並在標籤中加入discriminator-value鑒別器。該篇文章來討論複合主鍵映射,它是指主鍵是多列的組合,如今在設計資料庫時非常少用到複合主鍵,由於考慮到資料庫的最佳化,經常會把複合主鍵拆分到兩個表中,並利用一個關係表來維護兩個表的關係,關係表中不加入主鍵。
一、複合主鍵映射
複合主鍵映射須要在映射設定檔裡使用<composite-id>標籤,該標籤是指將一個類指定為對應的複合主鍵,它的name屬性須要指定類檔案裡定義的屬性值,並在該標籤中加入<key-property>子標籤。
Note:想要使用複合映射必需要將複合主鍵放到一個類中,也就是講複合主鍵屬性和其他屬性分到兩個類中,並將複合主鍵的類實現介面Serializable,該介面隸屬於java.io。
複合主鍵的映射關係的主鍵是由多個列複合而成的,相應到資料表中相當的簡單,例如以:
1、類檔案
這裡就拿的表來作為示範範例,在表中有兩個欄位年限和期間組合成為表的主鍵,所以分成的新類分別命名為FiscalYearPeriod和FiscalYearPeriodPK,當中FiscalYearPeriodPK類封裝表的主鍵屬性,FiscalYearPeriod類封裝其他屬性以及FiscalYearPeriodPK類。
1.1 FiscalYearPeriod.java
類中封裝有主要的屬性,並把FiscalYearPeriodPK類作為屬性封裝到類中,並在設定檔裡配置對應的映射,例如以下代碼:
package com.src.hibernate;import java.sql.Date;public class FiscalYearPeriod {//時間主鍵private FiscalYearPeriodPK fiscalYearPeriodPK;public FiscalYearPeriodPK getFiscalYearPeriodPK() {return fiscalYearPeriodPK;}public void setFiscalYearPeriodPK(FiscalYearPeriodPK fiscalYearPeriodPK) {this.fiscalYearPeriodPK = fiscalYearPeriodPK;}//開始日期private Date beginDate;public Date getBeginDate() {return beginDate;}public void setBeginDate(Date beginDate) {this.beginDate = beginDate;}//結束日期private Date endDate;public Date getEndDate() {return endDate;}public void setEndDate(Date endDate) {this.endDate = endDate;}//階段時間private String periodSts;public String getPeriodSts() {return periodSts;}public void setPeriodSts(String periodSts) {this.periodSts = periodSts;}}
1.2 FiscalYearPeriodPK.java
封裝主鍵屬性,該類是從FiscalYearPeriod類中分離出來的,包括了主要的主鍵屬性,而且須要實現介面Serializable,該類是要映射到設定檔裡<composite-id>標籤中要指定該類,代碼例如以下:
package com.src.hibernate;import java.io.Serializable;public class FiscalYearPeriodPK implements Serializable {//年限private int fiscalYear;public int getFiscalYear() {return fiscalYear;}public void setFiscalYear(int fiscalYear) {this.fiscalYear = fiscalYear;}//期間private int fiscalPeriod;public int getFiscalPeriod() {return fiscalPeriod;}public void setFiscalPeriod(int fiscalPeriod) {this.fiscalPeriod = fiscalPeriod;}}
2、設定檔
這裡有個疑問兩個類都是哪個須要加入對應檔?由於會使用<composite-id>標籤,所以僅僅須要為FiscalYearPeriod類加入映射就可以,在該對應檔裡加入相應複合主鍵標籤,並在標籤中加入相應的主鍵屬性,例如以下代碼:
<?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.src.hibernate.FiscalYearPeriod" table="t_fiscal_year_period_pk"><composite-id name="fiscalYearPeriodPK"><key-property name="fiscalYear"></key-property><key-property name="fiscalPeriod"></key-property></composite-id><property name="beginDate" type="date"/><property name="endDate" type="date"/><property name="periodSts"/></class></hibernate-mapping>
將上面的檔案產生相應的資料庫表,產生的sql語句例如以下:
drop table if exists t_fiscal_year_period_pkcreate table t_fiscal_year_period_pk (fiscalYear integer not null, fiscalPeriod integer not null, beginDate date, endDate date, periodSts varchar(255), primary key (fiscalYear, fiscalPeriod))
相應的表結構例如以:
3、資料操作
對應的對應檔配置好後,對應的資料操作就變得非常easy了,首先從寫入資料開始,向資料庫中寫入資料時會同一時候把兩個類寫入到資料庫中,所以此時這兩個類都必須轉化為Transient狀態,所以在儲存時須要首先將FiscalYearPeriod對象首先儲存到資料庫中,然後它會自己主動關聯複合屬性,將資訊儲存到資料庫中。
3.1 寫入操作
寫入的操作方法和曾經的寫入方法同樣,須要定義兩個對象,然後儲存對應的對象資訊到資料庫中,代碼例如以下:
public void testSave1(){//聲明會話對象Session session=null;try{//擷取會話對象session=HibernateUtils.getSession();//開啟會話session.beginTransaction();//建立綜合物件FiscalYearPeriodPK fiscalyearperiodpk=new FiscalYearPeriodPK();fiscalyearperiodpk.setFiscalPeriod(2014);fiscalyearperiodpk.setFiscalYear(2012);//建立對象FiscalYearPeriod fiscalyearperiod=new FiscalYearPeriod();fiscalyearperiod.setFiscalYearPeriodPK(fiscalyearperiodpk);session.save(fiscalyearperiod);//提交會話session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}
運行對應的測試方法,產生的SQL語句例如以下:
Hibernate: insert into t_fiscal_year_period_pk (beginDate, endDate, periodSts, fiscalYear, fiscalPeriod) values (?, ?, ?, ?, ?)
對應的資料庫檢視:
3.2 載入操作
對應的載入方法會和曾經不同,由於在該表中主鍵是複合屬性,所以須要建立一個類。在載入資料時須要建立主鍵對象,此時的主鍵就是一個對象,更須要為對象的屬性賦值,這樣才幹擷取對象,代碼例如以下:
public void testLoad1(){//聲明會話對象Session session=null;try{//擷取會話對象session=HibernateUtils.getSession();//開啟會話session.beginTransaction();//建立綜合物件FiscalYearPeriodPK fiscalyearperiodpk=new FiscalYearPeriodPK();fiscalyearperiodpk.setFiscalPeriod(2014);fiscalyearperiodpk.setFiscalYear(2012);FiscalYearPeriod fiscalyearperiod=(FiscalYearPeriod)session.load(FiscalYearPeriod.class,fiscalyearperiodpk);System.out.println("開始日期: "+fiscalyearperiod.getBeginDate()); //提交會話session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}
產生的結果,例如以下:
Hibernate: select fiscalyear0_.fiscalYear as fiscalYear0_0_, fiscalyear0_.fiscalPeriod as fiscalPe2_0_0_, fiscalyear0_.beginDate as beginDate0_0_, fiscalyear0_.endDate as endDate0_0_, fiscalyear0_.periodSts as periodSts0_0_ from t_fiscal_year_period_pk fiscalyear0_ where fiscalyear0_.fiscalYear=? and fiscalyear0_.fiscalPeriod=?開始日期: 2013-10-12
結語
複合主鍵的使用事實上非常easy,可是須要注意對象須要被拆分,主鍵自己須要一個類而且該類須要實現java.io.Serializable介面,其他的屬性再又一次產生新類,而且類的屬性中要有主鍵類的對象,對應的僅僅須要一個設定檔,在對應檔裡使用<composite-id>指明主鍵,並指明主鍵的屬性。
【Hibernate步步為營】--複合主鍵映射具體解釋