zoukankan      html  css  js  c++  java
  • 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却会报主键重复的错误。
  • 相关阅读:
    angular-指令
    microbit 范例课程
    microsoft 为microbit.org 设计的课程
    Microbit 翻译计划及IDE 中文化
    Microbit MicroPython 介绍
    micro:bit 软件生态系统介绍
    Microbit 硬件架构介绍
    TCP协议和UDP协议下的socket
    爬虫-链家二手房
    函数相关
  • 原文地址:https://www.cnblogs.com/wuxu/p/10830423.html
Copyright © 2011-2022 走看看