Hibernate_5 在hibernate 领域模型中单向多对

2017-12-14  本文已影响8人  mm_cuckoo

单向多对一(n - 1)

单向 n-1 关联只需从 n 的一端可以访问 1 的一端

下面介绍 n - 1 时,以 Order (订单)和用户(Customer) 为例: 一个用户能发出多个订单, 而一个订单只能属于一个客户. 从 Order 到 Customer 的关联是多对一关联; 而从 Customer 到 Order 是一对多关联。

步骤

  1. 在Order 中添加 Customer 的关联关系

  2. 在Order 的映射文件中配置映射多对一的关联关系。
    代码如下:下面是两种书写方式,效果是相同的

    <!-- 
        映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 
        name: 多这一端关联的一那一端的属性的名字
        class: 一那一端的属性对应的类名
        column: 一那一端在多的一端对应的数据表中的外键的名字
    -->
    <!--    <many-to-one name="customer" class="com.cfox.hibernate.n21.Customer" column="CUSTOMER_ID"/> -->  
    <many-to-one name="customer" class="com.cfox.hibernate.n21.Customer">
        <column name="CUSTOMER_ID"/>
    </many-to-one>
    

<many-to-one> 属性说明

属性 描述
name 属性名。
column (可选) 外间字段名。它也可以通过嵌套的 <column> 元素指定。
class (可选 ) 默认是通过反射得到属性类型): 关联的类的名字。
cascade(级联) (可选) 指明哪些操作会从父对象级联到关联的对象。
fetch (可选 - 默认为 select ) 在外连接抓取(outer-join fetching)和序列选择抓取(sequential select fetching)两者中选择其一。
update, insert (可选 - defaults to true ) 指定对应的字段是否包含在用于UPDATE 和/或 INSERT 的SQL语句中。如果二者都是false ,则这是一个纯粹的 “外源性(derived)”关联,它的值是通过映射到同一个(或多个)字段的某些其他属性得到 或者通过trigger(触发器)、或其他程序。
property-ref (可选) 指定关联类的一个属性,这个属性将会和本外键相对应。 如果没有指定,会使用对方关联类的主键。
access (可选 - 默认是 property ) Hibernate用来访问属性的策略。
unique (可选) 使用DDL为外键字段生成一个唯一约束。此外, 这也可以用作property-ref 的目标属性。这使关联同时具有 一对一的效果。
not-null (可选) 使用DDL为外键字段生成一个非空约束。
optimistic-lock (可选 - 默认为 true ) 指定这个属性在做更新时是否需要获得乐观锁定(optimistic lock)。 换句话说,它决定这个属性发生脏数据时版本(version)的值是否增长。
lazy (可选 - 默认为 proxy ) 默认情况下,单点关联是经过代理的。lazy="true" 指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。lazy="false" 指定此关联总是被预先抓取。
not-found (可选 - 默认为 exception ) 指定外键引用的数据不存在时如何处理: ignore 会将数据不存在作为关联到一个空对象(null)处理。
entity-name (optional) 被关联的类的实体名。

完整示例代码

public class Order {
    
    private Integer orderId;
    private String orderName;
    private Customer customer;
    
    //对应变量的get 和set 方法省略
}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-10-19 10:20:11 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.cfox.hibernate.n21.Order" table="ORDERS">
        <id name="orderId" type="java.lang.Integer">
            <column name="ORDERID" />
            <generator class="native" />
        </id>
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>
        
        <!-- 
            映射多对一的关联关系。 使用 many-to-one 来映射多对一的关联关系 
            name: 多这一端关联的一那一端的属性的名字
            class: 一那一端的属性对应的类名
            column: 一那一端在多的一端对应的数据表中的外键的名字
        -->
<!--    <many-to-one name="customer" class="com.cfox.hibernate.n21.Customer" column="CUSTOMER_ID"/> -->  
        <many-to-one name="customer" class="com.cfox.hibernate.n21.Customer">
            <column name="CUSTOMER_ID"/>
        </many-to-one>
  </class>
</hibernate-mapping>
public class Customer {
    private Integer customerId;
    private String name;
    
    //对应变量的get 和set 方法省略
}

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-10-19 10:20:11 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
    <class name="com.cfox.hibernate.n21.Customer" table="CUSTOMERS">
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMERID" />
            <generator class="native" />
        </id>
        <property name="name" type="java.lang.String">
            <column name="NAME" />
        </property>
        
    </class>
</hibernate-mapping>

双向一对多(1 - n)

双向一对多喝双向多对一是完全相同的,从多的一端可以访问多的一端,从一的一端也可以访问多的一端。

下面还是使用 Order 和Customer 来介绍双向一对多

先看示例代码:

实体bean

public class Customer {
    private Integer customerId;
    private String customerName;
    private Set<Order> orders = new HashSet<Order>();
    public Customer() {
    }
    public Customer(String customerName) {
        this.customerName = customerName;
    }
    // 省略set 和 get 方法
}

public class Order {
    private Integer orderId;
    private String orderName;
    private Customer customer;
    public Order() {
    }
    public Order(String orderName) {
        this.orderName = orderName;
    }
 // 省略set 和 get 方法
}

映射文件

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="com.cfox.hibernate.Order" table="ORDERS">
        <id name="orderId" type="java.lang.Integer">
            <column name="ORDER_ID" />
            <generator class="native" />
        </id>
        <property name="orderName" type="java.lang.String">
            <column name="ORDER_NAME" />
        </property>
        <many-to-one name="customer" class="com.cfox.hibernate.Customer">
            <column name="CUSTOMER_ID"/>
        </many-to-one>
    </class>
</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping >
    <class name="com.cfox.hibernate.Customer" table="CUSTOMER">
        <id name="customerId" type="java.lang.Integer">
            <column name="CUSTOMER_ID" />
            <generator class="native" />
        </id>
        <property name="customerName" type="java.lang.String">
            <column name="CUSTOMER_NAME" />
        </property>
        <set name="orders" table="ORDERS" inverse="true" order-by="ORDER_NAME DESC">
            <!-- 设定与所关联的持久化类对应的表的外键
                    column: 指定关联表的外键名
             -->
            <key column="CUSTOMER_ID"></key>
            <!-- 设定集合属性中所关联的持久化类
                    class: 指定关联的持久化类的类名
             -->
            <one-to-many class="com.cfox.hibernate.Order"/>
        </set>
    </class>
</hibernate-mapping>

介绍一下上面的几个元素:

映射关系图
image
下面介绍<set> 元素中的 inverse 属性
下面介绍<set> 元素中的 order-by 属性

在操作中注意

上一篇下一篇

猜你喜欢

热点阅读