hibernate学习之九(复合主键映射)

在实际开发中我们有时并不是使用一个字段当主键,有时也会使用2个以及以上字段当作主键,这种情况在hibernate中怎么实现那,hibernate给我们提供了2种方式实现,主键类实现和非主键类实现;
我们都用Customers 这个类中的cardId 和name做主键来讲解

非主键类实现

实体类

public class Customers implements java.io.Serializable {

    // Fields

    private String cardId;
    private String name;
    private String address;

映射文件

<hibernate-mapping>
    <class name="com.wfg.Customers" table="customers" catalog="ontomany">
        <composite-id >
            <key-property name="cardId" column="card_id" type="string"></key-property>
            <key-property name="name" column="_name" type="string"></key-property>
        </composite-id>
        <property name="address" type="java.lang.String">
            <column name="address_" length="15" />
        </property>
    </class>
</hibernate-mapping>

使用Schema创建表结构输出语句

drop table if exists ontomany.customers
create table ontomany.customers (card_id varchar(255) not null, _name varchar(255) not null, address_ varchar(15), primary key (card_id, _name))

测试代码:

Customers cus = new Customers();
            //cus.setAddress("shanghai");
            cus.setCardId("1000");
            cus.setName("张三");
            cus.setAddress("shanghai");
            //session.save(cus);


            Customers cus1 = new Customers();
            cus1.setName("张三");
            cus1.setCardId("1000");
            Customers cus2 = (Customers)session.get(Customers.class,cus1 );

            System.out.println(cus1.getAddress());
            System.out.println(cus2.getAddress());

打印的结果都为shanghai.证明从数据库中查询出数据了

主键类实现

我们接着来讲主键类实现方式
Customers 主键类

public class CustomersPermaryKey implements Serializable{

    private String cardId;
    private String name;
    public String getCardId() {
        return cardId;
    }
    public void setCardId(String cardId) {
        this.cardId = cardId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((cardId == null) ? 0 : cardId.hashCode());
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        return result;
    }
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        CustomersPermaryKey other = (CustomersPermaryKey) obj;
        if (cardId == null) {
            if (other.cardId != null)
                return false;
        } else if (!cardId.equals(other.cardId))
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        return true;
    }


}

Customers 类

public class Customers {

    // Fields

    private CustomersPermaryKey customersPermaryKey;
    private String address;

映射文件:

<hibernate-mapping>
    <class name="com.wfg.Customers" table="customers" catalog="ontomany">
        <composite-id name="customersPermaryKey" class="com.wfg2.CustomersPermaryKey" >
            <key-property name="cardId" column="card_id" type="string"></key-property>
            <key-property name="name" column="_name" type="string"></key-property>
        </composite-id>
        <property name="address" type="java.lang.String">
            <column name="address_" length="15" />
        </property>

    </class>
</hibernate-mapping>

这里和非主键类实现方式仅仅是在 composite-id 标签中加了下面2个属性:name=”customersPermaryKey” class=”com.wfg2.CustomersPermaryKey” >
使用Schema创建表结构输出语句

drop table if exists ontomany.customers
create table ontomany.customers (card_id varchar(255) not null, _name varchar(255) not null, address_ varchar(15), primary key (card_id, _name))

这里和非主键类实现方式一模一样的表结构
测试代码

CustomersPermaryKey key = new CustomersPermaryKey();
            key.setCardId("1000");
            key.setName("lisi");

            Customers cus = new Customers();
            cus.setCustomersPermaryKey(key);
            cus.setAddress("shanghai");
            session.save(cus);

总结:其实这2种实现方式不一样但是底层是一样的原理;
1) 类中的每个主键属性都对应到数据表中的每个主键列。
Hibernate要求具有联合主键的实体类实现 Serializable接口,并且重写 hashCode 与 equals 方法,重写这两个方法的原因在于Hibernate 要根据数据库的联合主键来判断某两行记录是否是一样的,如果一样那么就认为是同一个对象,如果不一样,那么就认为是不同的对象。这反映到程序领域中就是根据hashCode 与 equals 方法来判断某两个对象是否能够放到诸如Set 这样的集合当中。联合主键的实体类实现 Serializable 接口的原因在于使用get或load方法的时候需要先构建出来该实体的对象,并且将查询依据(联合主键)设置进去,然后作为 get或 load方法的第二个参数传进去即可。
2) 将主键所对应属性提取出一个类(称之为主键类) ,并且主键类
需要实现Serializable接口,重写equals方法与hashCode方法,原因与上面一样。

源码:
链接:http://pan.baidu.com/s/1boNXpfT 密码:054t

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值