hibernate 学习之二(一对多映射)

数据库中存在的映射关系如下:
一对一: 人和身份证
一对多:顾客和订单
多对多:学生和课程

今天我们先介绍一对多关系的应该(这里是双向一对多)

双向一对多

首先我们建立表结构
这里写图片描述
从pojo结构上看就是一的一方存在多的一方集合
多的一方存在一的一方实体类
这里写图片描述
customers 实体类

public class Customers implements java.io.Serializable {

    // Fields

    private Long id;
    private String name;
    private Set orderses = new HashSet(0);
    }

orders实体类

public class Orders implements java.io.Serializable {

    // Fields

    private Long id;
    private Customers customers;
    private String orderNumber;

映射文件

<hibernate-mapping>
    <class name="com.wfg.Customers" table="customers" catalog="ontomany">
        ....
        <set name="orderses" inverse="true" cascade="all">
            <key>
                <column name="CUSTOMER_ID" not-null="true" />
            </key>
            <one-to-many class="com.wfg.Orders" />
        </set>
    </class>
</hibernate-mapping>
  1. set元素包括以下属性:
    – name: 设定待映射的持久化类的属性名,这里为Customer类的 orders属性
    – cascade: 当取值为“save-update”,表示级联保存和更新。
    – inverse:当取值为“true”,表示在双向关联中,这一端为镜像端。
    表示关联关系的控制权,即按照关联的某一方的对象状态来同步跟新数据
    库。为true,表示由对方负责;为false,表示由自己负责维护
  2. set元素还包含两个子元素:key和one-to-many,one-to-many元素设定所关联的持久化类, 此处为Order类,key元素设定与所关联的持久化类对 应的表的外键,此处为ORDERS表的CUSTOMER_ID字 段。
<many-to-one name="customers" class="com.wfg.Customers" fetch="select">
            <column name="CUSTOMER_ID" not-null="true" />
        </many-to-one>

**name : 设定待映射的持久化类的属性名称即Orders类里面的属性customers
Class: 设定持久化类的属性的类型,和基本类型的Type一样的功能,此处设定customer属性为Customer类型
column: 设定和持久化类的属性对应的表的外键,此处为ORDERS表的外键CUSTOMER_ID**

测试代码

Customers customers = new Customers();
            customers.setId(new Long(1));
            customers.setName("customers1");
            //customers.setOrderses(new HashSet());

            Orders o1 = new Orders(customers, "o1");
            Orders o2 = new Orders(customers, "o2");
            Orders o3 = new Orders(customers,"o3");

            customers.getOrderses().add(o1);
            customers.getOrderses().add(o2);
            customers.getOrderses().add(o3);
            //这里仅仅保存customers
            session.save(customers);

执行效果
这里写图片描述

下面再细讲下cascade值的内容:
这里写图片描述

延迟加载

<set name="orderses" inverse="true" cascade="all" lazy="true">

lazy这个属性默认是true
这里写图片描述
这里发现一个现象就是先打印customers1又去查询的orders

这里写图片描述

这里我把session关闭后就抛出延迟加载的异常;

这里顺便把session.get()和session.load()方法也讲下:

  1. 即时加载:不管是否使用,马上会加载(从数据库取出放入内存),如session.get()方法。优点:响应速度快,不需要session一直打开状态。缺点:占用资源多。
  2. 延迟加载:代码执行后并不马上执行sql语句从数据库获取数据,而是在使用对象时才加载,如session.load()方法。注意,如果使用延迟加载,session要一直处于open状态,否则报异常。优点:占用资源少。缺点:响应速度慢,需要session一直打开状态。

自身一对多的概念

自身一对多用的比较多的地方就是在分类中使用最多即多级分类
这里写图片描述
实体类:

public class Categories implements java.io.Serializable {

    // Fields

    private Long id;
    private Categories categories;
    private String name;
    private Set categorieses = new HashSet(0);

映射文件

<hibernate-mapping>
    <class name="com.wfg.Categories" table="categories" catalog="ontomany">
        <id name="id" type="java.lang.Long">
            <column name="ID" />
            <generator class="native" />
        </id>
         <property name="name" type="java.lang.String">
            <column name="NAME" length="15" />
        </property>

        <many-to-one name="categories" class="com.wfg.Categories" fetch="select">
            <column name="CATEGORY_ID" />
        </many-to-one>

        <set name="categorieses" inverse="true" cascade="all">
            <key>
                <column name="CATEGORY_ID" />
            </key>
            <one-to-many class="com.wfg.Categories" />
        </set>
    </class>
</hibernate-mapping>

测试代码:

 try {
            Categories cat1 = new Categories(null, "cat1", new HashSet());
            Categories cat2 = new Categories(null, "cat2.1", new HashSet());
            Categories cat3 = new Categories(null, "cat2.2", new HashSet());
            Categories cat4 = new Categories(null, "cat2.2.1", new HashSet());
            Categories cat5 = new Categories(null, "cat2.2.2", new HashSet());
            Categories cat6 = new Categories(null, "cat2.2.3", new HashSet());

            //设定级联关系
            cat1.getCategorieses().add(cat2);
            cat1.getCategorieses().add(cat3);
            cat2.setCategories(cat1);
            cat3.setCategories(cat1);

            //设定第二次级联关系
            cat3.getCategorieses().add(cat4);
            cat3.getCategorieses().add(cat5);
            cat3.getCategorieses().add(cat6);

            cat4.setCategories(cat3);
            cat5.setCategories(cat3);
            cat6.setCategories(cat3);

            Categories cat8 = new Categories();
            cat8.setId(new Long(2));
            session.delete(cat8);
            //session.save(cat1);
            tx.commit();
        } catch (Exception e) {

源代码:
链接:http://pan.baidu.com/s/1pLk9gi3 密码:lvim

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值