hibernate 聯合主鍵 composite-id


如果表使用聯合主鍵(一個表有兩個以上的主鍵),你可以映射類的多個屬性為標識符屬性。如:<composite-id>元素接受<key-property> 屬性映射(單表映射)和<key-many-to-one>屬性映射作為子元素(多表映射)。
       <composite-id>
            <key-property name="stationNum" type="java.lang.String" column="STATIONNUM"/>
            <key-property name="observTimes" type="java.util.Date" column="OBSERVTIMES"/>
        </composite-id>
在持久化類必須重載equals()和hashCode()方法,來實現組合的標示符的相等判斷,實現Serializable接口也是必須的。
不幸的是,這種組合關鍵字的方法意味着一個持久化類是它自己的標識。除了對象自己之外, 沒有什么方便的“把手”可用。你必須初始化持久化類的實例,填充它的標識符屬性,再load() 組合關鍵字關聯的持久狀態。我們把這種方法稱為embedded(嵌入式)的組合標識符,在重要的應用中不鼓勵使用這種用法。
第二種方法我們稱為mapped(映射式)組合標識符 (mapped composite identifier),<composite-id>元素中列出的標識屬性不但在持久化類出現,還形成一個獨立的標識符類。
      <composite-id name="id" class="hibernate.RainId">
            <key-property name="stationNum" type="string">
                <column name="StationNum" length="5" />
            </key-property>
            <key-property name="observTimes" type="timestamp">
                <column name="ObservTimes" length="19" />
            </key-property>
        </composite-id>
在這個例子中,組合標示符類RainId和實體類都含有stationNum和observTimes屬性,標示符必須重載equals()和hashCode()並且實現Serializable接口。這種方法的缺點是出現了明顯的代碼重復。
下面列出的屬性是用來指定一個映射式組合標識符的:

mapped (可選, 默認為false): 指明使用一個映射式組合標識符,其包含的屬性映射同時在實體類和組合標識符類中出現。
class (可選,但對映射式組合標識符必須指定): 作為組合標識符類使用的類名. 
 
name (可選,但對這種方法而言必須): 包含此組件標識符的組件類型的名字.
access (可選 - 默認為property):
hibernate應該使用的訪問此屬性值的策略
class (可選 - 默認會用反射來自動判定屬性類型 ): 用來作為組合標識符的組件類的類名
第三種方式,被稱為identifier component(標識符組件)是我們對幾乎所有應用都推薦使用的方式。
例子:
POJO類
             public class Rain implements java.io.Serializable {
                 private RainId id;//聯合主鍵
                 private Date insertTimes;
                 private Integer precipitation;
                 private Integer threePrecip;
                 private Integer sixPrecip;
                 private Integer twelvePrecip;
                 private Integer twentyFourPrecip;
                 private Integer minuteRain0;
                 private Integer minuteRain1;
聯合主鍵bean
public class RainId implements java.io.Serializable {
    private String stationNum;
    private Date observTimes;
    public RainId() {
    }
    public RainId(String stationNum, Date observTimes) {
        this.stationNum = stationNum;
        this.observTimes = observTimes;
    }
 //重寫equals 和hashcode方法
    public boolean equals(Object other) {
        if ((this == other))
            return true;
        if ((other == null))
            return false;
        if (!(other instanceof RainId))
            return false;
        RainId castOther = (RainId) other;
        return ((this.getStationNum() == castOther.getStationNum()) || (this
                .getStationNum() != null && castOther.getStationNum() != null && this
                .getStationNum().equals(castOther.getStationNum())))
                && ((this.getObservTimes() == castOther.getObservTimes()) || (this
                        .getObservTimes() != null
                        && castOther.getObservTimes() != null && this
                        .getObservTimes().equals(castOther.getObservTimes())));
    }
    public int hashCode() {
        int result = 17;
        result = 37
                * result
                + (getStationNum() == null ? 0 : this.getStationNum()
                        .hashCode());
        result = 37
                * result
                + (getObservTimes() == null ? 0 : this.getObservTimes()
                        .hashCode());
        return result;
    }
配置映射文本 hbm.xml
 <class name="hibernate.Rain" table="rain" catalog="base">
        <composite-id name="id" class="hibernate.RainId">
            <key-property name="stationNum" type="string">
                <column name="StationNum" length="5" />
            </key-property>
            <key-property name="observTimes" type="timestamp">
                <column name="ObservTimes" length="19" />
            </key-property>
        </composite-id>
        <property name="insertTimes" type="timestamp">
            <column name="InsertTimes" length="19" />
        </property>
 
 
缺點:
1、聯合主鍵當中的字段不應該存在空值
   在實際的開發當中我發現,如果聯合主鍵中的某一字段為空值,那么將會導致通過該聯合主鍵查詢出來的結果為空值,這個問題不知道是hibernate的bug還是spring集成hibernate時產生的問題,總之在實際使用的時候最好保證作為聯合主鍵的字段都是有值的。
2、主鍵容易沖突
   hibernate聯合主鍵的另一個弊端就是存在主鍵重復的隱患,如果將某幾個字段做為聯合主鍵,在這些字段更新之后很可能造成重復,但數據庫中並不會報錯(存在其他不相同的字段),然而hibernate卻會報主鍵重復的錯誤。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM