精通Hibernate——映射一对多双向自身关联关系

首先我们来看下图:

每种商品类别代表一个Category对象,每一个Category可以和父列表关联,同时也可以和子类别关联,为了表达这种一对多的双向自身关联关系可以在Category类中定义两个属性:

parentCategory:引用父类别对象

childCategories:引用一组子类别对象

下面看看Category的源代码:

public class Category implements Serializable{
    private Lang id;
    private String name;
    private Category parentCategory;
    private Set childCategories;

    ....// get,set方法略,手写的
}

Category类的映射文件如下:

        <set name="childCategories" cascade="save-update" inverse="true">
            <key column="category_id" />
            <one-to-many class="com.fyw.Category" />
        </set>

下面我们来分析进行级联操作时的执行步骤:

(1)saveCategoryWidthCascade():当set属性的cascade为save-update时:

tx = session.beginTransaction();
Category foodCategory = new Category("food",null,new HashSet());
Category fruitCategory = new Category("fruit",null,new HashSet());
Category vegetableCategory = new Category("vegetable",null,new HashSet());
Category appleCategory = new Category("apple",null,new HashSet());
Category orangeCategory = new Category("orange",null,new HashSet());
Category tomatoCategory = new Category("tomato",null,new HashSet());
// 建立食品和水果之间的关系
foodCategory.getChildCategories().add(fruitCategory);
fruitCategory.setParentCategory(foodCategory);
// 建立食品和蔬菜之间的关系
foodCategory.getChildCategories().add(vegetableCategory);
vegetableCategory.setParentCategory(foodCategory);
// 建立水果和苹果之间的关系
fruitCategory.getChildCategories().add(appleCategory);
appleCategory.setParentCategory(fruitCategory);
// 建立水果和桔子之间的关系
fruitCategory.getChildCategories().add(orangeCategory);
orangeCategory.setParentCategory(fruitCategory);
// 建立西红柿和水果之间关系
fruitCategory.getChildCategories().add(tomatoCategory);
tomatoCategory.setParentCategory(fruitCategory);
session.save(foodCategory);
tx.commit();

当set的cascade为save-update时,Hibernate在持久化Category对象时会自动持久化关联的其他Category对象。

(2)modifyCategoryAssociation():该方法演示如何修改关联对象之间的关系。代码如下:

tx = session.beginTransaction();
Category tomatoCategory = findCategoryByName(session,"tomato");
Category fruitCategory = findCategoryByName(session,"fruit");
Category vegetableCategory = findCategoryByName(session,"vegetable");
// 建立西红柿和蔬菜之间关系
vegetableCategory.getChildCategories().add(tomatoCategory);
tomatoCategory.setParentCategory(vegetableCategory);
// 删除西红柿和水果之间关系
fruitCategory.getChildCategories().remove(tomatoCategory);
tx.commit();

首先通过findCategoryByName方法分别加载tomatoCategory,fruitCategory和vegetableCatgory对象并返回符合要求的:

public Category findCategoryByName(Session session,String name)throws Exception{
    List results = session.find("from Category as c where c.name =‘"+name+"‘");
    return (Category)results.iterator().next();
}

findCategoryByName方法和modifyCategoryAssociation方法共用一个session实例,通过findCategoryByName返回的Category仍处于持久化状态。

modifyCategoryAssociation方法会更新这三个对象之间的关联关系,当Hibernate在清理缓存中已持久化的对象时,会自动按照他们的状态改变来同步更新数据库。

虽然缓存中tomcatoCategory,fruitCategory,vegetableCategory这三个对象都发生了变化,但是set的inverse属性设置为true,Hibernate只执行一条sql语句。

时间: 2024-10-10 09:35:35

精通Hibernate——映射一对多双向自身关联关系的相关文章

Hibernate映射多对多双向关联关系(小案例)

多对多双向关联关系(Project(工程)/Emp(员工)为案例): 步骤如下: 1.创建Project类,并需要定义集合类型的Emp属性 public class Project { //编号 private Integer pid; //名称 private String pname; //定义集合类型的Emp属性 private Set<Emp> emps=new HashSet<Emp>(); public Integer getPid() { return pid; }

Hibernate 建立一对多双向关联关系

以下内容整理自<精通Hibernate>第二版 注:既然是双向关联,"一对多双向关联"和"多对一双向关联"是同一回事. 对象位于内存中,在内存中从一个对象导航到另一个对象显然比到数据库中查询数据的速度快多了.但是复杂的关联关联也会给编程带来麻烦,因此类与类之间是建立单向关联还是双向关联要由业务需求决定. 如果软件应用有大量这样的需求: 1.根据给定的客户,查询该客户的所有订单. 2.根据给定的订单,查询发出订单的客户. 根据以上需求,不妨为Custome

06章 映射一对多双向关联关系、以及cascade、inverse属性

当类与类之间建立了关联,就可以方便的从一个对象导航到另一个对象.或者通过集合导航到一组对象.例如: 对于给定的Emp对象,如果想获得与它关联的Dept对象,只要调用如下方法 Dept dept=emp.getDept(); //从Emp对象导航到关联的Dept对象 以Dept(部门)类和Emp(员工)类为例: 一.配置双向一对多关联 需在Dept类中增加一个集合类型的emps属性 private Set<Emp> emps=new HashSet<Emp>(); public Se

【SSH系列】Hibernate映射 -- 一对多关联映射

    映射原理       一对多关联映射和多对一关联映射的映射原理是一样一样的,所以说嘛,知识都是相通的,一通百通,为什么说一对多关联映射和多对一关联映射是一样的呢?因为她们都是在多的一端加入一个外键,指向一的一段,关联关系都是在多的一端进行维护,只是我们在写映射的时候发生了变化.       一对多和多对一的映射原理是一样的,但是她们之间也存在着小小的区别,毕竟世界上没有两片完全相同的叶子,她们之间的区别就是维护的关系不同,我们先来看多对一,多端维护一端的关系,在加载多端的时候,可以将一端

【SSH进阶之路】Hibernate映射——一对多关联映射(七)

上上篇博文[SSH进阶之路]Hibernate映射--一对一单向关联映射(五),我们介绍了一对一的单向关联映射,单向是指只能从人(Person)这端加载身份证端(IdCard),但是反过来,不能从身份证端加载人得信息. 上篇博文[SSH进阶之路]Hibernate映射--一对一双向关联映射(六),双向关联映射解决了单向关联映射只能从一端加载信息的缺陷,当然,双向关联映射并不影响存储,只影响加载.下面我们开始今天的内容: 一对多关联映射 映射原理 一对多关联映射和多对一关联映射的映射原理是一致的,

精通Hibernate——映射组成关系

建立域模型与关系型数据模型有着不同的出发点.域模型是由程序代码组成,通过细化持久化类的粒度提供代码可重用度,简化编程.关系数据模型由关系数据组成.存在数据冗余的情况下,需要把粗粒度的表拆分为具有外键参照关系的几个细粒度表,从而节省表的存储空间:另一方面在没有数据冗余的前提下,应尽可能减少表的数量,简化表之间的参照关系,以便提高数据库的访问速度. 由于建立域模型和关系型数据的原则不一样,使得持久化类的数目往往比数据库中表的数量要多,而且持久化类的属性并不和表字段一一对应,下面Customer类的h

《精通Hibernate:Java对象持久化技术详解》目录

图书信息:孙卫琴 电子工业出版社 第1章 Java应用分层架构及软件模型: 1.1 应用程序的分层体系结构 1.1.1 区分物理层和逻辑层 1.1.2 软件层的特征 1.1.3 软件分层的优点 1.1.4 软件分层的缺点 1.1.5 Java应用的持久化层 1.2 软件的模型 1.2.1 概念模型 1.2.2 关系数据模型 1.2.3 域模型 1.2.4 域对象 1.2.5 域对象之间的关系 1.2.6 域对象的持久化概念 1.3 小结 1.4 思考题第2章 Java对象持久化技术概述: 2.1

【SSH进阶之路】Hibernate映射——多对多关联映射(八)

上篇博文[SSH进阶之路]Hibernate映射--一对多关联映射(七),我们介绍了一对多关联映射,它是多对多关联映射的基础. 多对多映射是现实生活中最常见的映射,也是最容易理解的映射.废话少说,直接开始. 映射原理 不论是单向关联还是双向关联都是通过第三张表,将两个表中的主键放到第三张做一个关联.用第三张表来解决可能会造成数据冗余的问题. 举例 一个用户(User)对多个角色(Role),一个角色对多个用户. 分类 单向的多对多关联映射(单向User--->Role) 对象模型 关系模型 实例

精通Hibernate——建立双向一对多关联

当类与类之间建立了关联,就可以方便的从一个对象导航到另一个对象或者一组与他关联的对象. 对象位于内存中,在内存中从一个对象导航到另一个对象显然比到数据库中查询数据速度快多了.类与类之间到底建立双向还是单向都是由业务决定.以Customer和Order为例,如果软件应用有大量这样的需求: 根据客户可以查询该客户所有的订单 根据给定的订单可以查询发出订单的客户 以上需求就需要我们为Customer和Order类创建双向关联,代码如下: public class Customer{ private S