hibernate里面的一对多关系映射

来源:互联网 发布:淘宝强光手电 编辑:程序博客网 时间:2024/06/05 10:47

hibernate里面的一对多关系映射里面,一般都是指一张主表和一张从表。
在表示“多”的一方数据表里面增加一个外键,来指向表示“一”的那方数据表,“一”也就是我们所说的主表,而“多”就是我们所说的从表,接下来我们可以举个例子来进行说明:
(我所用的数据库是mysql)

这是一张顾客表(customer)的结构
这里写图片描述

这是一张订单表(order)的结构
这里写图片描述

在两张表里面,customer的cid和order里面的cid是一致的,因此我们可以将订单表里面的cid设置一个外键,将它和顾客表里面的cid进行绑定;

这里写图片描述

通过相应的绑定,当用户删除掉一条客户信息的时候,订单表里面的cid会自动变换为null值,在这里我设置了删除时为set null操作而不是cascade操作,因此不会出现级联删除(后边会讲如何进行级联删除操作)

然后便是顾客类的代码:

package com.sise.lh.model;import java.util.HashSet;import java.util.Set;public class Customer {    public int cid;    public String cname;    public Set<Order> order=new HashSet<Order>();    public Set<Order> getOrder() {        return order;    }    public void setOrder(Set<Order> order) {        this.order = order;    }    public String getCname() {        return cname;    }    public void setCname(String cname) {        this.cname = cname;    }    public int getCid() {        return cid;    }    public void setCid(int cid) {        this.cid = cid;    }}

然后便是订单order类:

package com.sise.lh.model;public class Order {    public String address;    public int cid;    public int id;    public int price;    public Customer customer;    public int getPrice() {        return price;    }    public void setPrice(int price) {        this.price = price;    }    public String getAddress() {        return address;    }    public int getCid() {        return cid;    }    public int getId() {        return id;    }    public Customer getCustomer() {        return customer;    }    public void setCustomer(Customer customer) {        this.customer = customer;    }    public void setAddress(String address) {        this.address = address;    }    public void setCid(int cid) {        this.cid = cid;    }    public void setId(int id) {        this.id = id;    }}

光有这些类的描述还不够,还需要有相应的配置才可以:
这里是顾客表的配置:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Mapping file autogenerated by MyEclipse Persistence Tools --><hibernate-mapping>    <class name="com.sise.lh.model.Customer" table="customer" catalog="test">        <id name="cid" column="cid">            <generator class="identity"></generator>        </id>        <property name="cname" type="java.lang.String">            <column name="cname" length="35" not-null="true" />        </property>        <!-- save-update:设置级联关系,这样的话可以支持顺时态和持久态的对象同时保存 -->        <!-- delete:设置级联关系进行删除 -->        <!-- delete-orphan:设置级联关系进行孤儿删除 -->        <set name="order"  >            <key column="cid"/>            <one-to-many class="com.sise.lh.model.Order"/>        </set>    </class></hibernate-mapping>

这里是订单表的配置:

<?xml version="1.0" encoding="utf-8"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Mapping file autogenerated by MyEclipse Persistence Tools --><hibernate-mapping>    <class name="com.sise.lh.model.Order" table="order" catalog="test">        <id name="id" column="id">            <generator class="identity"></generator>        </id>        <property name="address" type="java.lang.String">            <column name="address" length="35" not-null="true" />        </property>        <property name="price" type="java.lang.Integer">            <column name="price" length="6" not-null="true" />        </property>        <many-to-one name="customer" class="com.sise.lh.model.Customer" column="cid">        </many-to-one>          </class></hibernate-mapping>

接下来是进行相应的测试部分:

@Test    public void testManyToOne()    {        Transaction transaction= session.beginTransaction();        Customer c=(Customer) session.get(Customer.class, 13);        Order o1=new Order();        o1.setAddress("深圳01");        o1.setPrice(144);        Order o2=new Order();        o2.setAddress("南京01");        o2.setPrice(188);        c.getOrder().add(o1);        c.getOrder().add(o2);        session.save(c);        session.save(o1);        session.save(o2);        transaction.commit();    }

成功之后的截图如下:

这里写图片描述

由于我们之前在设置外键的时候只是设置为了set null操作,因此当用户表里面的信息被删除之后,订单表里面的信息还不会立马就被删除,只是有所绑定的cid字段会被设置为null而已。
接下来便是删除操作部分:

@Test    public void testDelete()    {        Transaction transaction=session.beginTransaction();        Customer c=(Customer) session.get(Customer.class, 13);        session.delete(c);        transaction.commit();    }

这里写图片描述

果然和开始预期所想的结果一样,那么这个时候,又是否有办法在不接触到数据库的前提下,通过hibernate的配置来进行订单表里面整条数据的级联删除呢?
答案是有的,可以通过修改xml里面cascade属性进行操作,也就是这顾客类customer.hbm.xml的配置:

    <set name="order"  cascade="delete">            <key column="cid"/>            <one-to-many class="com.sise.lh.model.Order"/>    </set>

只需要在上边添加cascade=”delete”属性即可实现

关于顾客表里面的cascade状态我参考了另外一篇博客里面的内容

http://www.cnblogs.com/amboyna/archive/2008/02/18/1072260.html

此时我又进行了相应的操作,再次插入两条数据:

这里写图片描述

接下来再是一次执行删除操作

@Test    public void testDelete()    {        Transaction transaction=session.beginTransaction();        Customer c=(Customer) session.get(Customer.class, 18);        session.delete(c);        transaction.commit();    }

通过cascade=”delete”属性的绑定,这次数据被完全删除了