Hibernate(四)---映射关系

(一)映射组成关系
这里写图片描述
· Hibernate把持久化类的属性分为两种:

  • 值(value)类型:没有 OID, 不能被单独持久化, 生命周期依赖于所属的持久化类的对象的生命周期.
  • 实体(entity)类型: 有 OID, 可以被单独持久化, 有独立的生命周期.
    · Hibernate 使用 <component> 元素来映射组成关系, 该元素表名 pay 属性是 Worker 类一个组成部分, 在 Hibernate 中称之为组件.
    · 配置文件:
    这里写图片描述
    例:
hibernate-mapping package="com.ty.hibernate.entities">
    <class name="Worker" table="WORKER">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>

        <!-- 映射组成关系 -->
        <component name="pay" class="Pay">
            <parent name="worker"/>
            <!-- 指定组成关系的组件的属性 -->
            <property name="monthlyPay" column="MONTHLY_PAY"></property>
            <property name="yearPay" column="YEAR_PAY"></property>
            <property name="vocationWithPay" column="VOCATION_WITH_PAY"></property>
        </component>

    </class>
</hibernate-mapping>

(二)映射一对多关联关系
(1)单向n–1
· 单向 n-1 关联只需从 n 的一端可以访问 1 的一端;
· 域模型: 从 Order 到 Customer 的多对一单向关联需要在Order 类中定义一个 Customer 属性, 而在 Customer 类中无需定义存放 Order 对象的集合属性;
这里写图片描述
· 关系数据模型:ORDERS 表中的 CUSTOMER_ID 参照 CUSTOMER 表的主键
这里写图片描述
· Hibernate使用 <many-to-one> 元素来映射多对一关联关系

<!-- 

            name: 多这一端关联的一那一端的属性的名字
            class: 一那一端的属性对应的类名
            column: 一那一端在多的一端对应的数据表中的外键的名字
-->
<many-to-one name="customer" class="Customer" column="CUSTOMER_ID"></many-to-one>

(2)双向n–1
· 双向 1-n 与 双向 n-1 是完全相同的两种情形.
· 双向 1-n 需要在 1 的一端可以访问 n 的一端, 反之依然.
· 域模型:从 Order 到 Customer 的多对一双向关联需要在Order 类中定义一个 Customer 属性, 而在 Customer 类中需定义存放 Order 对象的集合属性.
这里写图片描述
· 关系数据模型:ORDERS 表中的 CUSTOMER_ID 参照 CUSTOMER 表的主键.
这里写图片描述
· 在持久化类中定义集合属性时必须把属性声明为 Java 接口类型
· 在定义集合属性时, 通常把它初始化为集合实现类的一个实例. 这样可以提高程序的健壮性, 避免应用程序访问取值为 null 的集合的方法抛出 NullPointerException

private Set<Order> order = new HashSet<>();

· Hibernate 使用 <set> 元素来映射 set 类型的属性

        <!-- 映射 1 对多的那个集合属性 -->
        <!-- set: 映射 set 类型的属性, table: set 中的元素对应的记录放在哪一个数据表中. 该值需要和多对一的多的那个表的名字一致 -->
        <!-- inverse: 指定由哪一方来维护关联关系. 通常设置为 true, 以指定由多的一端来维护关联关系 -->
        <!-- cascade 设定级联操作. 开发时不建议设定该属性. 建议使用手工的方式来处理 -->
        <!-- order-by 在查询时对集合中的元素进行排序, order-by 中使用的是表的字段名, 而不是持久化类的属性名,order-by 属性中还可以加入 SQL 函数
  -->
        <set name="orders" table="ORDERS" inverse="true" order-by="ORDER_NAME DESC">
            <!-- 执行多的表中(即指定Order表的外键列名)的外键列的名字 -->
            <key column="CUSTOMER_ID"></key>
            <!-- 指定映射类型 -->
            <one-to-many class="Order"/>
        </set>

注:cascade 属性
· 在对象 – 关系映射文件中, 用于映射持久化类之间关联关系的元素, <set>, <many-to-one> 和 <one-to-one> 都有一个 cascade 属性, 它用于指定如何操纵与当前对象关联的其他对象
这里写图片描述

注:
若三个表之间通过一对多映射(即Customer表一对多映射Order表(Order表中含有Customer的外键Customer_Id),Order表一对多映射DetailOrder(DetailOrder表中含有Order的外键Order_ID)),这种情况下只能通过链接三个表才能将数据映射到DetailOrder对象的各个属性(详情查看51Shop项目中JavaBean模型的SuperType,SubType及Goods的映射关系)

//通过Hql查询
String hql = "From DetailOrder d Join Fetch d.orderId o join fetch o.customerId "
List<DetailOrder> detailOrder = getSession().createQuery(hql).list()

(三)映射一对一关联关系
(1)基于外键映射的一对一
· 关系数据模型
这里写图片描述
· 对于基于外键的1-1关联,其外键可以存放在任意一边,在需要存放外键一端,增加many-to-one元素。为many-to-one元素增加unique=“true” 属性来表示为1-1关联.

<many-to-one name="manager" class="com.ty.model2.oneToOne.foregin.Manager"
          >
          <column name="MANAGER_ID" unique="true"/>
        </many-to-one>

· 另一端需要使用one-to-one元素,该元素使用 property-ref 属性指定使用被关联实体主键以外的字段作为关联字段

<one-to-one name="deparment" class="com.ty.model2.oneToOne.foregin.Deparment" property-ref="manager" ></one-to-one>

注:若不使用property-ref属性:
这里写图片描述
(2)基于主键映射的一对一
· 关系数据模型
这里写图片描述
· 基于主键的映射策略:指一端的主键生成器使用 foreign 策略,表明根据”对方”的主键来生成自己的主键,自己并不能独立生成主键. <param> 子元素指定使用当前持久化类的哪个属性作为 “对方”.

//Deparment表
    <class name="Department" table="DEPARTMENTS">

        <id name="deptId" type="java.lang.Integer">
            <column name="DEPT_ID" />
            <!-- 使用外键的方式来生成当前的主键 -->
            <generator class="foreign">
                <!-- property 属性指定使用当前持久化类的哪一个属性的主键作为外键 -->
                <param name="property">mgr</param>
            </generator>
        </id>

        <property name="deptName" type="java.lang.String">
            <column name="DEPT_NAME" />
        </property>

        <!--  
        采用 foreign 主键生成器策略的一端增加 one-to-one 元素映射关联属性,
        其 one-to-one 节点还应增加 constrained=true 属性, 以使当前的主键上添加外键约束
        -->
        <one-to-one name="mgr" class="Manager" constrained="true"></one-to-one>
//Manager表  
   <class name="com.atguigu.hibernate.one2one.primary.Manager" table="MANAGERS">

        <id name="mgrId" type="java.lang.Integer">
            <column name="MGR_ID" />
            <generator class="native" />
        </id>

        <property name="mgrName" type="java.lang.String">
            <column name="MGR_NAME" />
        </property>

        <one-to-one name="dept" 
            class="com.atguigu.hibernate.one2one.primary.Department"></one-to-one>

    </class>

(四)映射多对多关联关系
(1)单项n-n关系
· 关系数据模型
这里写图片描述
· n-n 的关联必须使用连接表.
· 与 1-n 映射类似,必须为 set 集合元素添加 key 子元素,指定 CATEGORIES_ITEMS 表中参照 CATEGORIES 表的外键为 CATEGORIY_ID. 与 1-n 关联映射不同的是,建立 n-n 关联时, 集合中的元素使用 many-to-many. many-to-many 子元素的 class 属性指定 items 集合中存放的是 Item 对象, column 属性指定 CATEGORIES_ITEMS 表中参照 ITEMS 表的外键为 ITEM_ID.

 <!-- table: 指定中间表 -->
        <set name="items" table="CATEGORIES_ITEMS">
            <key>
                <column name="C_ID" />
            </key>
            <!-- 使用 many-to-many 指定多对多的关联关系. column 执行 Set 集合中的持久化类在中间表的外键列的名称  -->
            <many-to-many class="Item" column="I_ID"></many-to-many>
        </set>

(2)双向n-n关系
· 关系数据模型
这里写图片描述
· 双向 n-n 关联需要两端都使用集合属性
· 双向n-n关联必须使用连接表
· 集合属性应增加 key 子元素用以映射外键列, 集合元素里还应增加many-to-many子元素关联实体类
· 在双向 n-n 关联的两边都需指定连接表的表名及外键列的列名. 两个集合元素 set 的 table 元素的值必须指定,而且必须相同。set元素的两个子元素:key 和 many-to-many 都必须指定 column 属性,其中,key 和 many-to-many 分别指定本持久化类和关联类在连接表中的外键列名,因此两边的 key 与 many-to-many 的column属性交叉相同。也就是说,一边的set元素的key的 cloumn值为a,many-to-many 的 column 为b;则另一边的 set 元素的 key 的 column 值 b,many-to-many的 column 值为 a.
· 对于双向 n-n 关联, 必须把其中一端的 inverse 设置为 true, 否则两端都维护关联关系可能会造成主键冲突.
(五)继承映射
(1)采用 subclass 元素的继承映射
· 采用 subclass 的继承映射可以实现对于继承关系中父类和子类使用同一张表
· 因为父类和子类的实例全部保存在同一个表中,因此需要在该表内增加一列,使用该列来区分每行记录到低是哪个类的实例—-这个列被称为辨别者列(discriminator).
· 在这种映射策略下,使用 subclass 来映射子类,使用 class 或 subclass 的 discriminator-value 属性指定辨别者列的值
· 所有子类定义的字段都不能有非空约束。如果为那些字段添加非空约束,那么父类的实例在那些列其实并没有值,这将引起数据库完整性冲突,导致父类的实例无法保存到数据库中
这里写图片描述

<hibernate-mapping>
    <class name="com.ty.model2.subclass.Person" table="PERSONS" discriminator-value="Person">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <discriminator column="TYPE" type="java.lang.String"/>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="AGE" />
        </property>
        <subclass name="com.ty.model2.subclass.Student" discriminator-value="STUDENT">
          <property name="school" type="java.lang.String"/>
        </subclass>
    </class>
</hibernate-mapping>

(2)采用 joined-subclass 元素的继承映射
· 采用 joined-subclass 元素的继承映射可以实现每个子类一张表
· 采用这种映射策略时,父类实例保存在父类表中,子类实例由父类表和子类表共同存储。因为子类实例也是一个特殊的父类实例,因此必然也包含了父类实例的属性。于是将子类和父类共有的属性保存在父类表中,子类增加的属性,则保存在子类表中。
· 在这种映射策略下,无须使用鉴别者列,但需要为每个子类使用 key 元素映射共有主键。
· 子类增加的属性可以添加非空约束。因为子类的属性和父类的属性没有保存在同一个表中。
这里写图片描述

<hibernate-mapping>
    <class name="com.ty.model2.joined.Person" table="PERSON">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="AGE" />
        </property>
        <joined-subclass name="com.ty.model2.joined.Student">
           <key column="STUDENT_ID" not-null="true"></key>
           <property name="school" type="java.lang.String"/>
        </joined-subclass>
    </class>
</hibernate-mapping>

(3)采用 union-subclass 元素的继承映射
· 采用 union-subclass 元素可以实现将每一个实体对象映射到一个独立的表中。
· 子类增加的属性可以有非空约束 — 即父类实例的数据保存在父表中,而子类实例的数据保存在子类表中。
· 子类实例的数据仅保存在子类表中, 而在父类表中没有任何记录
· 在这种映射策略下,子类表的字段会比父类表的映射字段要多,因为子类表的字段等于父类表的字段、加子类增加属性的总和
· 在这种映射策略下,既不需要使用鉴别者列,也无须使用 key 元素来映射共有主键.
· 使用 union-subclass 映射策略是不可使用 identity 的主键生成策略, 因为同一类继承层次中所有实体类都需要使用同一个主键种子, 即多个持久化实体对应的记录的主键应该是连续的. 受此影响, 也不该使用 native 主键生成策略, 因为 native 会根据数据库来选择使用 identity 或 sequence.
这里写图片描述

<hibernate-mapping>
    <class name="com.ty.model2.union.Person" table="PERSON">
        <id name="id" type="java.lang.Integer">
            <column name="ID" />
            <generator class="hilo" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        <property name="age" type="java.lang.Integer">
            <column name="AGE" />
        </property>

        <union-subclass name="com.ty.model2.union.Student">
           <property name="school" type="java.lang.String"/>
        </union-subclass>
    </class>
</hibernate-mapping>

(4)三种映射方式比较
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明 YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明YOLO高分设计资源源码,详情请查看资源内容中使用说明
hibernate-jpa-2.1-api 1.0.2是一个Java持久化规范的实现库。它是基于JPA(Java Persistence API)2.1规范的Hibernate实现。Hibernate是一个流行的ORM(对象关系映射)框架,用于在Java应用程序和关系数据库之间进行数据持久化。 该版本的hibernate-jpa-2.1-api是对JPA 2.1规范的实现,并且是Hibernate团队为了确保应用程序与Java EE 7兼容性而发布的一个版本。 JPA是一种使用对象模型操作数据库的标准规范,它提供了一组API,使开发人员可以使用面向对象的方式访问和操作数据库。Hibernate作为一个JPA的实现,提供了许多附加的功能和特性,使得开发人员可以更加简化和灵活地进行数据库操作。 通过使用hibernate-jpa-2.1-api,开发人员可以使用JPA的标准API,以及Hibernate提供的独有特性,来实现应用程序的数据持久化需求。它提供了实体管理器,用于管理实体对象的生命周期,以及CRUD操作。此外,它还提供了用于查询和各种持久化注解的支持。 通常情况下,使用hibernate-jpa-2.1-api需要将其添加到项目的依赖中,并与其他必需的Hibernate库一起使用。开发人员需要熟悉JPA的基本概念和API,并且理解Hibernate特有的扩展和配置选项。 总的来说,hibernate-jpa-2.1-api 1.0.2提供了开发人员在使用JPA进行数据持久化时的基本工具和功能。它是Hibernate团队为了支持JPA 2.1规范而发布的一个版本,开发人员可以使用它来简化和灵活地操作数据库。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值