欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hibernate_级联操作、关联关系映射

程序员文章站 2022-05-02 08:16:34
...

1. 实体之间的关系
<1>一对多
 一个用户可以生成多个订单,一个订单只属于一个用户。

建表原则:
        在多的一方创建一个字段,作为外键,指向另一方的主键。

<2>多对多
 一个学生可以选择多门课,一门课可以被多个学生选择。

建表原则:
        创建第三张表,中间表至少有两个字段,分别作为外键指向多对多双方的主键。

<3>一对一
 一个人只能有一个身份证号,一个身份证号只属于一个人。

建表原则:
            唯一主键:一对一的双方,假设一方是多的关系,需要在多的一方创建一个字段,
                     作为外键,指向一的一方的主键,但是在外键上添加一个unique。
            主键对应:一对一的双方,通过主键进行对应。

2. 一对多的配置
<1>创建两个实体

* 客户实体:
public class Customer {
    private Integer cid;
    private String cname;
    // 一个客户有多个订单.
    private Set<Order> orders = new HashSet<Order>();
    public Integer getCid() {
        return cid;
    }
        public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Set<Order> getOrders() {
        return orders;
    }
    public void setOrders(Set<Order> orders) {
        this.orders = orders;
    }

}
* 订单实体:
public class Order {
    private Integer oid;
    private String addr;
    // 订单属于某一个客户.放置一个客户的对象.
    private Customer customer;
    public Integer getOid() {
        return oid;
    }
    public void setOid(Integer oid) {
        this.oid = oid;
    }
    public String getAddr() {
        return addr;
    }
    public void setAddr(String addr) {
        this.addr = addr;
    }
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
}

<2>建立映射

*Customer.hbm.xml
<hibernate-mapping>
    <class name="cn.itcast.hibernate3.demo2.Customer" table="customer">
        <!-- 配置唯一标识 -->
        <id name="cid" column="cid">
            <generator class="native"/>
        </id>
        <!-- 配置普通属性 -->
        <property name="cname" column="cname" length="20"/>

        <!-- 建立映射 -->
        <!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. -->
        <set name="orders">
            <!-- <key>标签中column:用来描述一对多多的一方的外键的名称. -->
            <key column="cno"></key>
            <!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 -->
            <one-to-many class="cn.itcast.hibernate3.demo2.Order"/>
        </set>
    </class>
</hibernate-mapping>


*Order.hbm.xml
<hibernate-mapping>
    <class name="cn.itcast.hibernate3.demo2.Order" table="orders">
        <!-- 配置唯一标识  -->
        <id name="oid" column="oid">
            <generator class="native"/>
        </id>
        <!-- 配置普通属性 -->
        <property name="addr" column="addr" length="50"/>
        <!-- 配置映射 -->
        <!-- 
        <many-to-one>标签
            name    :关联对象的属性的名称.
            column  :表中的外键名称.
            class   :关联对象类的全路径
        -->
        <many-to-one name="customer" column="cno" class="cn.itcast.hibernate3.demo2.Customer"/>
    </class>
</hibernate-mapping>

<3>在核心配置文件中加载映射。
 hibernate.cfg.xml

<!-- 通知Hibernate加载那些映射文件 -->
    <mapping resource="cn/itcast/hibernate3/demo2/Customer.hbm.xml" />
    <mapping resource="cn/itcast/hibernate3/demo2/Order.hbm.xml" /> 

3. 级联操作
 所谓的级联就是:操作当前对象的时候,关联的对象如何处理。
<1>级联保存
cascade=”save-update”
级联方向性:
* 保存客户的时候,选择级联订单。
* 保存订单的时候,选择级联客户。

        <!-- 建立映射 -->
        <!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. -->
        <set name="orders" cascade="save-update" inverse="true">
            <!-- <key>标签中column:用来描述一对多多的一方的外键的名称. -->
            <key column="cno"></key>
            <!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 -->
            <one-to-many class="cn.itcast.hibernate3.demo2.Order"/>
        </set>

<2>级联删除
 在没有设置级联的情况下,默认将外键置为null,删除数据记录。

@Test
    // 删除一个客户:
    // 默认的情况下,将外键置为null,删除数据记录.
    public void demo6(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();

        // 删除的时候有两种:
        // 先查询在删除的情况:
        Customer customer = (Customer) session.get(Customer.class, 1);
        session.delete(customer);

        tx.commit();
        session.close();
    }

 设置级联之后的删除

@Test
    // 级联删除:删除客户的时候级联删除订单.
    // 在Customer.hbm.xml的<set>标签上配置cascade="delete"
    public void demo7(){
        Session session = HibernateUtils.openSession();
        Transaction tx = session.beginTransaction();

        // 级联删除:先查询,在删除的方式.
        Customer custoemr = (Customer) session.get(Customer.class, 1);
        session.delete(custoemr);

        tx.commit();
        session.close();
    }

4. 级联取值

none            :不使用级联
dave-update     :保存或更新的时候级联
delete          :删除的时候级联
all             :除了孤儿删除以外的所有级联.
delete-orphan   :孤儿删除(孤子删除).
* 仅限于一对多.只有一对多时候,才有父子存在.认为一的一方是父亲,多的一方是子方.
* 当一个客户与某个订单解除了关系.将外键置为null.订单没有了所属客户,相当于一个孩子没有了父亲.将这种记录就删除了.

all-delete-orphan :包含了孤儿删除的所有的级联

5. 维护双向关联产生多余的SQL

配置inverse=”true”:在那一端配置.那么那一端放弃了外键的维护权.
* 一般情况下,一的一方去放弃.
cascade:操作关联对象.
inverse:控制外键的维护.