精通Hibernate——级联操纵对象

来源:互联网 发布:软件自动汉化工具 编辑:程序博客网 时间:2024/05/21 09:30

当我们加载一个类时session会加载所有和该类直接关联或者间接关联的对象。
在对象关系映射文件中,用于映射持久化类之间关联关系的元素,如、和元素,都有一个cascade属性,他用于指定如何操纵与当前关联的对象,他的可选属性如下:
none:在保存、更新或删除对象时,忽略其他关联的对象,他是cascade默认属性
save-update:当通过session的save、update以及saveOrUpdate方法来保存或更新当前对象时,级联保存所有关联的新建的临时对象,并且级联更新所有关联的游离对象
delete:当通过session的delete方法删除当前对象时,级联删除所有关联的对象
all:包含save-update以及delete行为以外,对当前对象执行evict或lock操作时,也会对所关联的持久化对象执行evict或lock操作
delete-orphan:删除所有和当前对象解除关联关系的对象
all-delete-orphan:包含all和delete-orphan行为
我们以下面类的关系为例:
这里写图片描述
1、级联保存临时对象
saveFoodCategory()方法先创建三个Category临时对象,建立他们之间的关联关系,然后调用saveOrUpdate方法保存foodCategory对象。

public void saveFoodCategory() throws Exception{    Category foodCategory = new Category("food",null,new Hashset());    Category fruitCategory = new Category("fruit",null,new Hashset());    Category appleCategory = new Category("apple",null,new Hashset());    // 建立食品类别和水果类别之间的关系    foodCategory.addChildCategory(fruitCategory);    // 建立水果类别和苹果类别之间的关系    fruitCategory.addChildCategory(appleCategory);    saveOrUpdate(foodCategory);}

saveOrUpdate方法调用session的saveOrUpdate方法来保存foodCategory对象。执行步骤如下:
1.由于foodCatogory为临时对象,因此session调用save方法来保存foodCategory对象
2.session通过foodCategory.getChildCategories方法导航到fruitCategory临时对象,调用save方法来保存fruitCategroy临时对象
3.session通过fruitCategory.getChildCategories方法导航到appleCategory临对象,调用save方法来保存appleCategory临时对象
Session在清理缓存的时候执行三条insert语句

insert into categories (name,category_id,id) values("food",null,1);insert into categories (name,category_id,id) values("fruit",1,2);insert into categories (name,category_id,id) values("food",2,3);

2、更新持久化对象
saveOrangeCategory()方法用于持久化一个orangeCategory对象,他会先调用findCategoryByName(session,”fruit”)方法,由于该查询方法与saveOrangeCategory()方法公用一个session,因此,他返回的fruitCategory对象处于持久化状态。接下来创建一个orangeCategory临时对象,建立fruitCategory与orangeCategory之间的关联关系。
3、持久化临时对象
saveVegetableCategory()方法用于持久化一个vegetableCategory临时对象
saveVegetableCategory()方法先调用findCategoryByName(“food”)方法,该方法不与saveVegetableCategory()方法公用一个session,因此返回的foodCategory对象处于游离状态。接下来创建一个vegetableCategory临时对象,建立foodCategory与vegetableCategory之间的关联关系。最后调用saveOrUpdate()保存vegetableCategory对象:

public void saveVegetableCategory() throws Exception{    // 返回的foodCategory是游离对象    Category foodCategory = findCategoryByName("food");    Category vegetableCategory = new Category("vegetable",null,new HashSet());    // foodCategory游离对象与vegetableCategory临时对象关联    foodCategory.addChildCategory(vegetableCategory);    saveOrUpdate(vegetableCategory);}

saveOrUpdate方法调用Session的saveOrUpdate来保存vegetableCategory对象,Session的saveOrUpdate执行以下步骤:
1.由于vegetableCategory为临时对象,因此Session调用save方法持久化vegetableCategory对象。
2.Session通过vegetableCategory.getParentCategory()方法导航到foodCategory对象,由于foodCategory对象为游离对象,因此调用update方法更新foodCategory对象。
3.Session通过foodCategory.getChildCategories方法导航到fruitCategory对象,由于fruitCategory对象为游离对象,因此调用update方法更新fruitCategory对象
4、更新游离对象
updateVegetableCategory方法用于更新vegetableCategory对象的name属性,并且创建一个tomatoCategory对象,他与vegetableCategory对象关联
updateVegetableCategory方法先调用findCategoryByName(“vegetable”)方法,该查询方法不与updateVegetableCategory方法公用一个Session,因此返回的vegetableCategory对象处于游离状态。接下来修改vegetableCategory对象的name属性,然后创建一个tomatoCategory临时对象,建立vegetableCategory与tomatoCategory之间的关联关系,最后调用saveOrUpdate方法封信vegetableCategory对象

public void updateVegetableCategory() throws Exception{    //返回的vegetableCategory是游离对象    Category vegetableCategory = findCategoryByName("vegetable");    vegetableCategory.setName("green vegetable");    Category tomatoCategory = new Category("tomato",null,new HashSet());    //vegetableCategory游离对象与tomato临时对象关联    vegetableCategory.addChildCategory(tomatoCategory);    saveOrUpdate(vegetableCategory);}

5、遍历对象图
navigateCategories方法先调用findCategoryByName(“fruit”)方法,由于该查询方法不与navegateCategories公用一个Session,因此他返回的fruitCategory对象处于游离状态。接下来调用navigateCategories(fruitCategory,categories)取得所有关联的Category游离对象

   public void navigateCategores() throws Exception{    Category fruitCategory = findCategoryByName("fruit");    HashSet categories = new HashSet();    navigateCategories(fruitCategory,categories);    //打印categories集合中所有的Category对象    for(Iterator it = categories.iterator();it.hasNext();){        System.out.println(((Category)it.next()).getName());    }}

navigateCategories方法利用递归算法,遍历所有与fruitCategory关联的父类别及类别Category对象,把他们存放在一个Set集合中:

private void navigateCategories(Category category,Set categories){    if(categories.contains(category) || category == null) return;    categories.add(category);    //递归遍历父类Category    navigateCategories(category.getParentCategory(),categories);    Set childCategories = category.getChildCategores();    if(childCategories == null) return;    //递归遍历所有子类Category    for(Iterator it = childCategores.interator();it.hasNext();){        navigateCategories((Category)it.next(),categories);    }}
1 0
原创粉丝点击