精通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语句。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值