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

Hibernate在one-to-many实现父子关系的自动插入

阅读更多

      这是个老生长谈的问题,在学习Hibernate的时候,当时是认为永远都用不上,因为现在数据库设计并没有严格按照范式来进行设计,更多的时候采用逻辑外键关系,在代码中去控制这种业务逻辑。但是,这次在'景点+门票'的1-N关系模型时候产品设计了插入景点信息时候就录入N个门票类型信息。所以,个人认为在插入(CMS中数据的录入时候)使用起来这种级联增删改比较方便,因为插入不会带来巨大数据库压力(hibbernate的这种级联操作确实效率不高,从打印出来的HQL中可以明显看到,Hibernate对N的一端也是一条插入的)。

      注意:在数据库表设计的时候,子表中设置物理外键关联父表 不是必须的 ,而且现在的数据库设计更多的是偏重逻辑外键关系,这的确会为后期的工作带来很大的方便。

 

景点 和 门票类型的POJO和hbm代码

景点POJO

public class TbScenery {
	private String id;
	private String jdname;
	
	private List<TbSceneryTickets> tbSceneryTickets;
	//getter setter....
}

景点hbm

<?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="TbScenery" table="TB_SCENERY">
        <id name="id" type="java.lang.String">
            <column name="ID" length="32" />
            <generator class="sequence" >  
    			<param name="sequence">SEQ_SCENERY</param>  
    		</generator>
        </id>
        <property name="jdname" type="java.lang.String">
            <column name="JDNAME" length="500" />
        </property>
	<!-- 这里需要Parent一端设置inverse="true" cascade="all"-->
	<list name="tbSceneryTickets" lazy="false" inverse="true" cascade="all">
		<key><column name="SCENERY_ID" /></key>
		<index column="ID" type="java.lang.String" />
		<one-to-many class="TbSceneryTickets" />
	</list>
    </class>
</hibernate-mapping>

 

门票POJO:

public class TbSceneryTickets implements java.io.Serializable {
	private String id;
	private String sceneryId;//外键
	private String typeName;
	//getter setter....
}

门票hbm

<hibernate-mapping>
	<class name="TbSceneryTickets" table="TB_SCENERY_TICKETS" lazy="false">	
        <id name="id" type="java.lang.String">
            <column name="ID" length="32" />
            <generator class="sequence" >  
    			<param name="sequence">SEQ_SCENERY_TICKET</param>  
    		</generator>
        </id>
		
		<property name="sceneryId" type="java.lang.String" column="SCENERY_ID"
			length="32" />
		<property name="typeName" type="java.lang.String" column="TYPE_NAME"
			length="100" />
	</class>
</hibernate-mapping>

 

测试后发现在做更新,删除操作的时候的时候没有任何问题,只是在做如下的插入操作的时候会发现插入失败(这里的方法用了事务控制):

public void test() {
	TbScenery scenery = new TbScenery();
	scenery.setJdname("东方明珠");
	
	//由于景点对象的id主键 和 门票对象的id主键都是从序列中获取到的,这里没法设置这些值。
	//也没有办法为门票对象赋景点外键sceneryId的值
	TbSceneryTickets ticket1 = new TbSceneryTickets();
	ticket1.setTypeName("成人票");
	
	TbSceneryTickets ticket2 = new TbSceneryTickets();
	ticket1.setTypeName("儿童票");
	
	List<TbSceneryTickets> tbSceneryTickets = new ArrayList<TbSceneryTickets>();
	tbSceneryTickets.add(ticket1);
	tbSceneryTickets.add(ticket2);
	scenery.setTbSceneryTickets(tbSceneryTickets);
	
	dao.saveOrUpdate(scenery);
}
 

      原因是:在新建’景点‘,并且有了n个’门票类型的时候‘,不能一次性提交这个’景点‘对象,tbSceneryTickets赋值给scenery前需要先save一下scenery,因为scenery是一个new出来的对象,不是一个已经被持久化过的对象,对它进行tbSceneryTickets赋值,Hibernate并不能够检查到它的状态。其实说得浅显些,就是scenery(景点对象)自己都没有id标识,那每个TbSceneryTickets对象(门票类型对象)怎么知道外键是什么呢?

     对于one-to-many,一般都是如下操作:

public void test() {
	TbScenery scenery = new TbScenery();
	scenery.setJdname("东方明珠");
	
	//这个步骤结束后,scenery就有自己的主键了,通过debug可以非常清楚的看到
	dao.saveOrUpdate(scenery);
	
	TbSceneryTickets ticket1 = new TbSceneryTickets();
	ticket1.setTypeName("成人票");
	//当然如果不放心,可以自己手工给ticket赋外键
	ticket1.setSceneryId(scenery.getId());
	
	TbSceneryTickets ticket2 = new TbSceneryTickets();
	ticket1.setTypeName("儿童票");
	ticket2.setSceneryId(scenery.getId())
	
	List<TbSceneryTickets> tbSceneryTickets = new ArrayList<TbSceneryTickets>();
	tbSceneryTickets.add(ticket1);
	tbSceneryTickets.add(ticket2);
	scenery.setTbSceneryTickets(tbSceneryTickets);
	
	dao.saveOrUpdate(scenery);
}

 

在项目中可以使用这个原理来轻松完成one-to-many的级联操作(增删改查)。

分享到:
评论

相关推荐

    Hibernate_3.2.0_符合Java习惯的关系数据库持久化

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    HibernateAPI中文版.chm

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    hibernate3.2中文文档(chm格式)

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    Hibernate+中文文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    最全Hibernate 参考文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 三重关联...

    Hibernate中文详细学习文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联...

    Hibernate教程

    7.2.5. 一对多关联(One-to-many Associations) 7.3. 高级集合映射(Advanced collection mappings) 7.3.1. 有序集合(Sorted collections) 7.3.2. 双向关联(Bidirectional associations) 7.3.3. 三重关联...

    hibernate 体系结构与配置 参考文档(html)

    一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,涉及...

    Hibernate 中文 html 帮助文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,...

    Hibernate3+中文参考文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 三重关联...

    hibernate 框架详解

    一对多关联(One-to-many Associations) 7.3. 高级集合映射(Advanced collection mappings) 7.3.1. 有序集合(Sorted collections) 7.3.2. 双向关联(Bidirectional associations) 7.3.3. 三重关联...

    hibernate3.04中文文档.chm

    22.2. 双向的一对多关系(Bidirectional one-to-many) 22.3. 级联生命周期(Cascading lifecycle) 22.4. 级联与未保存值(Cascades and unsaved-value) 22.5. 结论 23. 示例:Weblog 应用程序 23.1. 持久化类 ...

    Hibernate参考文档

    6.2.5. 一对多关联(One-to-many Associations) 6.3. 高级集合映射(Advanced collection mappings) 6.3.1. 有序集合(Sorted collections) 6.3.2. 双向关联(Bidirectional associations) 6.3.3. 双向关联,...

Global site tag (gtag.js) - Google Analytics