`
fehly
  • 浏览: 248409 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Hibernate组件映射

阅读更多

组件Components

除了粗粒度的对象模型设计(一个表映射成一个持久化类)之外,还可以采用细粒度的对象模型,吧一个表的映射成两个或者多个类。

被细化出来的类,可以称为组件(Component)

组件映射

组件映射的单向关联

组件映射的双向关联

组件集合映射 

使用组件集合,可以让组件对象的集合依附于一个持久化对象上

 

本来说自己写的,网上看了看资料太全面了  就收集整理好了

 

Component这个概念在Hibernate中几处不同的地方为了不同的目的被重复使用.

依赖对象(Dependent objects)

Component是一个被包含的对象,它作为值类型被持久化,而非一个实体。“component(组件)”这一术语指的是面向对象的合成概念(而并不是系统构架层次上的组件的概念)举个例子, 你可以对人(Person)如以下这样来建模:

public class Person {
    private java.util.Date birthday;
    private Name name;
    private String key;
    public String getKey() {
        return key;
    }
    private void setKey(String key) {
        this.key=key;
    }
    public java.util.Date getBirthday() {
        return birthday;
    }
    public void setBirthday(java.util.Date birthday) {
        this.birthday = birthday;
    }
    public Name getName() {
        return name;
    }
    public void setName(Name name) {
        this.name = name;
    }
    ......
    ......
}

 

public class Name {
    char initial;
    String first;
    String last;
    public String getFirst() {
        return first;
    }
    void setFirst(String first) {
        this.first = first;
    }
    public String getLast() {
        return last;
    }
    void setLast(String last) {
        this.last = last;
    }
    public char getInitial() {
        return initial;
    }
    void setInitial(char initial) {
        this.initial = initial;
    }
}

 

现在,姓名(Name)是作为人(Person)的一个组成部分。需要注意的是:需要对姓名 的持久化属性定义getter和setter方法,但是不需要实现任何的接口或申明标识符字段。

以下是这个例子的Hibernate映射文件:

<class name="eg.Person" table="person">
    <id name="Key" column="pid" type="string">
        <generator class="uuid.hex"/>
    </id>
    <property name="birthday" type="date"/>
    <component name="Name" class="eg.Name"> <!-- class attribute optional -->
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>
    </component>
</class>

 

人员(Person)表中将包括pid, birthday, initial, firstlast等字段。

就像所有的值类型一样, Component不支持共享引用。Component的值为空从语义学上来讲是专有的。 每当 重新加载一个包含组件的对象,如果component的所有字段为空,那么将Hibernate将假定整个component为 空。对于绝大多数目的,这样假定是没有问题的。

Component的属性可以是Hibernate类型(包括Collections, many-to-one 关联, 以及其它Component 等等)。嵌套Component不应该作为特殊的应用被考虑(Nested components should not be considered an exotic usage)。 Hibernate趋向于支持设计细致(fine-grained)的对象模型。

<component> 元素还允许有 <parent>子元素 ,用来表明component类中的一个属性返回包含它的实体的引用。

<class name="eg.Person" table="person">
    <id name="Key" column="pid" type="string">
        <generator class="uuid.hex"/>
    </id>
    <property name="birthday" type="date"/>
    <component name="Name" class="eg.Name">
        <parent name="namedPerson"/> <!-- reference back to the Person -->
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>
    </component>
</class>

 

在集合中出现的依赖对象

Hibernate支持component的集合(例如: 一个元素是“姓名”这种类型的数组)。 你可以使用<composite-element>标签替代<element>标签来定义你的component集合。

<set name="someNames" table="some_names" lazy="true">
    <key column="id"/>
    <composite-element class="eg.Name"> <!-- class attribute required -->
        <property name="initial"/>
        <property name="first"/>
        <property name="last"/>
    </composite-element>
</set>

 

注意,如果你决定定义一个元素是联合元素的Set,正确地实现equals()hashCode()是非常重要的。

组合元素可以包含component但是不能包含集合。如果你的组合元素自身包含component, 必须使用<nested-composite-element>标签。这是一个相当特殊的案例 - 组合元素的集合自身可以包含component。 这个时候你就应该考虑一下使用one-to-many关联是否会更恰当。 尝试对这个组合元素重新建模为一个实体-但是需要注意的是,虽然Java模型和重新建模前 是一样的,关系模型和持久性语义上仍然存在轻微的区别。

请注意如果你使用<set>标签,一个组合元素的映射不支持可能为空的属性. 当删除对象时, Hibernate必须使用每一个字段的来确定一条记录(在组合元素表中,没有单个的关键字段), 如果有为null的字段,这样做就不可能了。你必须作出一个选择,要么在组合元素中使用不能为空的属性, 要么选择使用<list>, <map>,<bag> 或者 <idbag>而不是 <set>

组合元素有个特别的案例,是组合元素可以包含一个<many-to-one> 元素。类似这样的映射允许你映射一个many-to-mang关联表作为组合元素额外的字段。(A mapping like this allows you to map extra columns of a many-to-many association table to the composite element class.) 接下来的的例子是从OrderItem的一个多对多的关联关系,而 purchaseDate, pricequantityItem的关联属性。

 

<class name="eg.Order" .... >
    ....
    <set name="purchasedItems" table="purchase_items" lazy="true">
        <key column="order_id">
        <composite-element class="eg.Purchase">
            <property name="purchaseDate"/>
            <property name="price"/>
            <property name="quantity"/>
            <many-to-one name="item" class="eg.Item"/> <!-- class attribute is optional -->
        </composite-element>
    </set>
</class>

 

即使三重或多重管理都是可能的:

<class name="eg.Order" .... >
    ....
    <set name="purchasedItems" table="purchase_items" lazy="true">
        <key column="order_id">
        <composite-element class="eg.OrderLine">
            <many-to-one name="purchaseDetails" class="eg.Purchase"/>
            <many-to-one name="item" class="eg.Item"/>
        </composite-element>
    </set>
</class>

 

在查询中,组合元素使用的语法是和关联到其他实体的语法一样的。

组件作为Map的索引(Components as Map indices )

<composite-index>元素允许你映射一个Component类作为Map的key, 但是你必须确定你正确的在这个类中重写了hashCode()equals()方法。

组件作为联合标识符(Components as composite identifiers)

你可以使用一个component作为一个实体类的标识符。 你的component类必须满足以下要求:

  • 它必须实现java.io.Serializable接口

  • 它必须重新实现equals()hashCode()方法, 始终和组合关键字在数据库中的概念保持一致

你不能使用一个IdentifierGenerator产生组合关键字。作为替代应用程序必 须分配它自己的标识符.

既然联合标识符必须在对象存储之前被分配,我们就不能使用标识符的unsaved-value来把刚刚新建的实例和在先前的session保存的实例区分开来。

如果你希望使用saveOrUpdate()或者级联保存/更新(cascading save / update),你应该实现 Interceptor.isUnsaved()。使用<composite-id> 标签(它和<component>标签有同样的属性和元素)代替<id>标签。 下面有个联合标识符类的定义:

<class name="eg.Foo" table"FOOS">
    <composite-id name="compId" class="eg.FooCompositeID">
        <key-property name="string"/>
        <key-property name="short"/>
        <key-property name="date" column="date_" type="date"/>
    </composite-id>
    <property name="name"/>
    ....
</class>

 

这时候,任何到FOOS的外键也同样是联合的, 在你其他类的映射文件中也必须同样定义。 一个到Foo的定义应该像以下这样:

<many-to-one name="foo" class="eg.Foo">
<!-- the "class" attribute is optional, as usual -->
    <column name="foo_string"/>
    <column name="foo_short"/>
    <column name="foo_date"/>
</many-to-one>

 

新的 <column> 标签同样被用于包含多个字段的自定义类型(This new columntag is also used by multi-column custom types)。 事实上在各个地方它都是一个可选的字段属性。要定义一个元素是Foo的集合类,要这样写:

<set name="foos">
    <key column="owner_id"/>
    <many-to-many class="eg.Foo">
        <column name="foo_string"/>
        <column name="foo_short"/>
        <column name="foo_date"/>
    </many-to-many>
</set>

 

另一方面,<one-to-many>元素通常不定义字段.

如果 Foo 自己包含集合, 那么他们也需要使用联合外键。

<class name="eg.Foo">
    ....
    ....
    <set name="dates" lazy="true">
        <key>   <!-- a collection inherits the composite key type -->
            <column name="foo_string"/>
            <column name="foo_short"/>
            <column name="foo_date"/>
        </key>
        <element column="foo_date" type="date"/>
    </set>
</class>

 

 动态组件 (Dynamic components)

你甚至可以映射Map类型的属性:

<dynamic-component name="userAttributes">
    <property name="foo" column="FOO"/>
    <property name="bar" column="BAR"/>
    <many-to-one name="baz" class="eg.Baz" column="BAZ"/>
</dynamic-component>

 

<dynamic-component>映射的语义上来讲,它和<component>是相同的。 这种映射类型的优点在于通过修改映射文件,就可以具有在部署时检测真实属性的能力.(利用一个DOM解析器, 是有可能在运行时刻操作映射文件的。)

分享到:
评论
1 楼 yulanlian 2012-07-31  
我想问楼主一个问题,就是我采用的都是ssh2框架,然后我在做用户信息管理时,用到了组件映射,可是我现在迷茫的是,我在处理action和Service时,应当如何做?是对多个实例化类操作,还是只对注册信息类进行操作。
组件映射的好处和作用到底是什么?

相关推荐

    hibernate组件映射

    在Hibernate中,组件映射是将一个类的实例作为另一个类的一个属性进行持久化的过程。这种映射方式有助于保持数据模型的整洁和逻辑性,同时也使得数据的管理更为高效。下面我们将详细探讨Hibernate的组件映射。 一、...

    Hibernate组件映射(annotation/xml)

    《Hibernate组件映射:Annotation与XML的融合》 在Java持久化领域,Hibernate是一个不可或缺的框架,它提供了强大的对象关系映射(ORM)能力。本文将深入探讨Hibernate中的组件映射,包括使用注解(Annotation)和...

    Hibernate组件映射代码详解

    "Hibernate组件映射代码详解" titre的知识点: * Hibernate组件映射代码的概念和实现 * 组件关联映射的属性和特点 * Hibernate组件映射的优点和应用场景 描述的知识点: * Hibernate组件映射代码的详细解释 *...

    Hibernate教程09_关系映射之组件映射

    在本教程中,我们将深入探讨Hibernate中的一个关键概念——关系映射中的组件映射。Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,它允许开发人员以面向对象的方式处理数据库操作,极大地简化了数据层...

    component(组件映射)

    由于无法直接访问链接,以下将根据常见的Hibernate组件映射实践来阐述相关知识点。 1. **定义组件**:在Hibernate中,组件通常是一个无标识的类,它不对应数据库中的单独记录,而是作为其他有标识实体的一部分。...

    Spring+Hibernate 自动映射

    1. **依赖注入(Dependency Injection,DI)**:Spring通过XML配置或注解方式,将Hibernate的相关组件如SessionFactory、Session等注入到需要使用它们的类中,避免了手动创建和管理这些对象。 2. **事务管理...

    hibernate组件之间的关联

    组件映射允许将一个类的属性作为另一个类的一部分,类似于 Java 中的嵌套类。使用 @Component 或 @Embeddable 注解来标记可嵌入的组件类,然后在父类中使用 @Embedded 或 @EmbeddableId 来引用它们。 **联合主键...

    Hibernate_code

    5. **Hibernate_Component**:这部分可能包含了Hibernate组件映射的示例。组件是对象的一部分,可以被嵌入到其他对象中,类似于数据库中的复合类型。通过@Component或@Embeddable注解,可以将一个类声明为组件,并在...

    hibernate组建映射代码

    在实际应用中,我们还需要创建一个SessionFactory,它是Hibernate的核心组件,通过它来获取Session实例,进而进行CRUD操作。SessionFactory的创建通常在应用启动时完成,例如: ```java Configuration config = new...

    hibernate的映射文件配置

    接下来,我们将深入探讨映射文件的基本结构和核心组件配置。 #### 映射文件基本结构 映射文件的基本结构包含以下关键元素: ```xml &lt;!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD ...

    11 映射-- 组件映射(人类与姓名类)

    在IT行业中,组件映射是软件开发中的一个重要概念,特别是在对象关系映射(ORM)框架中,如Hibernate。本文将详细解析"11 映射-- 组件映射(人类与姓名类)"这一主题,结合标签"源码"和"工具",探讨如何在Hibernate中...

    Hibernate教程17_继承映射

    在Java世界中,ORM(对象关系映射)框架如Hibernate极大地简化了数据库操作。本教程主要探讨的是Hibernate中的“继承映射”特性,这是一项关键功能,它允许我们将复杂的类继承结构映射到数据库表中。通过继承映射,...

    Hibernate继承映射

    【Hibernate继承映射】是Java开发中...以上就是关于Hibernate继承映射、一对一关系、组件映射以及HQL的基础知识,这些概念和实践技巧在Java企业级开发中非常常见,熟练掌握能有效提高数据操作的效率和代码的可维护性。

    hibernate映射Oracle中LONG类型

    同时,自定义类型也需要与 Hibernate 框架的其他组件集成,例如数据类型转换、SQL 语句生成等。 使用自定义类型映射 Oracle 中的 LONG 类型字段是解决 Hibernate 框架中 LONG 类型字段读写问题的一种有效方法。通过...

    hibernate中的相关组件的介绍

    ### Hibernate中的相关组件介绍 #### 一、Hibernate配置文件(`hibernate.cfg.xml`) 在Hibernate框架中,默认的配置文件被命名为`hibernate.cfg.xml`。此配置文件是Hibernate初始化过程中的关键组成部分,它定义...

    springmvc+hibernate多表映射

    在IT行业中,SpringMVC和Hibernate是两个非常重要的框架,它们分别是用于构建Web应用程序和对象关系映射(ORM)的工具。在这个“springmvc+hibernate多表映射”的主题中,我们将深入探讨如何在SpringMVC项目中集成...

    hibernate对象关系映射实例

    Hibernate的核心组件包括配置文件、实体类、映射文件以及SessionFactory和Session接口。 1. **配置文件**:通常为`hibernate.cfg.xml`,用来配置数据库连接信息,如JDBC驱动、URL、用户名和密码等。 2. **实体类**...

    深入理解hibernate映射文件

    ### 深入理解Hibernate...总之,Hibernate映射文件是实现对象关系映射的核心组件之一,通过对映射文件的合理配置,可以高效地完成Java对象与数据库表之间的映射,从而简化数据库操作并提高代码的可维护性和可扩展性。

Global site tag (gtag.js) - Google Analytics