码迷,mamicode.com
首页 > Web开发 > 详细

hibernate 映射关系—关系映射(一对多)

时间:2015-06-26 12:54:02      阅读:153      评论:0      收藏:0      [点我收藏+]

标签:hibernate

一对多关联关系是数据库表格关系中最常用的关联关系,有很多例子,比如顾客和订单的关系,下面来学习hibernate中一对多的实现。
1、数据库设计

CREATE TABLE `customer` (
  `cid` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) NOT NULL,
  `phone` varchar(11) NOT NULL,
  `address` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  `register_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  PRIMARY KEY (`cid`),
  UNIQUE KEY `AK_name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

CREATE TABLE `orders` (
  `oid` bigint(20) NOT NULL AUTO_INCREMENT,
  `cid` bigint(20) NOT NULL,
  `price` double NOT NULL,
  `name` varchar(256) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL,
  PRIMARY KEY (`oid`),
  KEY `fk_cid` (`cid`),
  CONSTRAINT `fk_cid` FOREIGN KEY (`cid`) REFERENCES `customer` (`cid`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8;

2、配置文件

<hibernate-mapping package="com.study.hibernate.hbm">
    <class name="Customer" table="customer" catalog="hibernate">
        <id name="cid" type="java.lang.Long">
            <column name="cid" />
            <generator class="identity" />
        </id>
        <property name="name" type="string">
            <column name="name" length="64" not-null="true" unique="true" />
        </property>
        <property name="phone" type="string">
            <column name="phone" length="11" not-null="true" />
        </property>
        <property name="address" type="string">
            <column name="address" length="256" not-null="true" />
        </property>
        <property name="registerTime" type="timestamp">
            <column name="register_time" length="19" not-null="true" />
        </property>
        <set name="orderses" table="orders" inverse="true" lazy="true" fetch="select">
            <key>
                <column name="cid" not-null="true" />
            </key>
            <one-to-many class="Orders" />
        </set>
    </class>
</hibernate-mapping>

<hibernate-mapping package="com.study.hibernate.hbm">
    <class name="Orders" table="orders" catalog="hibernate">
        <id name="oid" type="java.lang.Long">
            <column name="oid" />
            <generator class="identity" />
        </id>
        <many-to-one name="customer" class="Customer" fetch="select">
            <column name="cid" not-null="true" />
        </many-to-one>
        <property name="price" type="double">
            <column name="price" precision="22" scale="0" not-null="true" />
        </property>
        <property name="name" type="string">
            <column name="name" length="256" not-null="true" />
        </property>
    </class>
</hibernate-mapping>

3、持久化类

public class Customer implements java.io.Serializable {

    private Long cid;
    private String name;
    private String phone;
    private String address;
    private Date registerTime;
    private Set orderses = new HashSet(0);
}
public class Orders implements java.io.Serializable {

    private Long oid;
    private Customer customer;
    private double price;
    private String name;
}

4、关键点总结
延迟加载方面
1)使用lazy和fetch两个字段来配置延迟加载,这里的延迟加载不是说load的延迟加载,而是指关联对象的延迟加载
2)lazy=false方式对createQuery和get操作方式有效,fetch=join的方式只对get方式的操作有效
3)当fetch=join时,若连接的表层级太深,可能影响性能,这个可以在Hibernate属性文件中设置max_fetch_depth属性来控制连接的层级数。
4)非延迟加载时,没有设置batch-size,当使用find查找Customer,Order的获取是每个Customer都会发出一条sql语句进行查找,若设置batch-size,则会优化Orders的sql查找为in的情况,即减少sql语句的条数,该属性只能用在一端的配置中,即集合配置中。

级联操作方面
1)一端save时可以单独保存,也可以级联保存多端的数据,只需设置cascade的属性为save-update或以上;多端save时需要注意,由于外键约束的原因,多端保存时一端要么在数据库中有相应的记录,要么多端级联同时保存一端,级联配置也很简单,只需要配置cascade的属性为save-update或以上
2)由于外键约束一端delete时必须设置delete操作的级联属性cascade=all或以上;多端delete时一般不需要级联处理,只需删除自身就ok
3)更新一端时会同时更新多端的数据;更新多端时若只是基本信息对一端没有影响,若是更新关联的一端,则需要同时更新新的一端(若新的一端之前还有相应的多端时,还需更新多端)即至少2条update语句,其他的update语句根据新的一端相应的多端数据记录来决定;最后还有一种情况需要注意,即一端先remove多端的某个对象,再update一端时,若需要在数据库中删除remove的多端对象,需要设置cascade=all-delete-orphan,否则不会级联删除
4)当casecade=all,则是支持save-update和delete的关联操作。而cascade=all-delete-orphan一般用于set中,作用是在解除父子关系时,自动删除不属于父对象的子对象, 也支持级联删除和级联保存更新,比如如下代码,提交时会删除order记录。customer.getOrders().removre(order),order.setCustomer(null),tx.commit();

inverse
inverse的意思是反转,反转什么呢,这里是指反转维护关联关系变化的权利,若inverse=true则说明维护关联关系变化的权利反转,交给对方来处理,一般one端不维护关联关系都是交个many端来维护即设置inverse=true,在many-to-one中inverse不支持配置,默认即处理关联关系的变化。
比如,当inverse=true时,往Customer添加order然后保存customer时,只会有insert语句;inverse=false,则表示感应对象更新关系的变化,当往customer添加order然后保存customer时,不但有insert语句,还有update语句,明显这个时候的update是多余的。

单向和双向
单向和双向一般应该根据业务的需要来设置,单向无非就是在双向的基础上去掉某一端的关联关系配置,使得变成单向关联,具体就不细说了。

hibernate 映射关系—关系映射(一对多)

标签:hibernate

原文地址:http://blog.csdn.net/pingnanlee/article/details/46632261

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!