hibernate详解(四)---对象关系之级联

Hibernate对象关系之级联

级联及组合关系:强聚合关系,代表整体和部分之间不能分开,整体和部分单独存在没有意义;

组合关系的两个对象都是在一个模块当中管理的;都是在整体那个对象的模块中管理;

(1)以销售订单(主对象)和订单的明细数据(子对象)为例分析:

  • 对于销售订单对象来说:
    1、存在一个列表;
    2、添加:在添加页面需要添加销售订单对象上的属性,还需要添加这个销售订单的明细数据;
    3、修改:仍然在销售订单的编辑页面中完成;
    4、删除:在销售订单列表中删除销售订单;
  • 对于销售订单明细对象来说:
    1、对于销售订单明细对象,不需要列表;
    2、添加:
    a、在销售订单对象的添加的时候,可以添加销售订单明细对象;
    b、在销售订单对象的保存,可以添加销售订单明细对象;
    3、修改:在销售订单对象的修改方法中完成的;
    4、删除:在销售订单对象的修改方法中完成的;在删除销售订单的时候,也要去删除这个销售订单的明细;

(2)分析执行流程

  • 只需要有销售订单对象的DAO接口就可以了,销售订单明细的CRUD都是在销售订单对象的DAO中完成的;
  • save:
    1、保存销售订单对象;
    2、保存销售订单对象对应的销售订单明细对象;
  • update:
    1、修改销售订单对象(游离);
    2、保存新的销售订单明细对象(临时对象);
    3、修改修改过的销售订单明细对象(游离);
    4、删除去掉了的销售订单明细对象(删除和主对象没有关系的销售订单明细对象);
  • delete:
    1、删除销售订单对象的明细;
    2、删除主对象;

(3)参考代码如下:

SaleBill对象:

public class SaleBill {
	private Long id;
	private String sn;
	private Date inputTime;
	private Set<SaleBillItem> items = new HashSet<SaleBillItem>();
}

SaleBillItem对象

public class SaleBillItem {
	private Long id;
	private String product;
	private SaleBill bill;
}

映射文件

<class name="SaleBill">
    <id name="id">
        <generator class="native"/>
    </id>
    <property name="sn"/>
    <set name="items" inverse="true" cascade="all-delete-orphan">
        <key column="BILL_ID" />
        <one-to-many class="SaleBillItem"/>
    </set>
</class>

<class name="SaleBillItem">
    <id name="id">
        <generator class="native"/>
    </id>
    <property name="product"/>
    <many-to-one name="bill" column="BILL_ID" />
</class>

SaleBillDAO接口

public interface ISaleBillDAO {

	void save(SaleBill saleBill);

	void update(SaleBill saleBill);

	void delete(Long id);
	
	SaleBill get(Long id);
}

SaleBillDAOImpl实现类

public class SaleBillDAOImpl implements ISaleBillDAO {

	@Override
	public void save(SaleBill bill) {
		Session session = HibernateUtil.getInstance().openSession();
		session.beginTransaction();
		session.save(bill);
		session.getTransaction().commit();
		session.close();
	}

	@Override
	//这个update方法是用来更新SaleBillItem的
	public void update(SaleBill saleBill) {
		Session session = HibernateUtil.getInstance().openSession();
		session.beginTransaction();
		SaleBill old=(SaleBill)session.get(SaleBill.class, saleBill.getId());
		List<SaleBillItem> deletes=new ArrayList<SaleBillItem>();
		for(SaleBillItem item:old.getItems()){
			boolean find=false;
			for(SaleBillItem newItem:saleBill.getItems()){
				if(newItem.getId()!=null && item.getId().equals(newItem.getId())){
					find=true;
				}
			}
			if(!find){
				deletes.add(item);
			}
		}
		old.getItems().removeAll(deletes);
		for(SaleBillItem item:deletes){
			item.setBill(null);
		}
		session.update(old);
		session.getTransaction().commit();
		session.close();
	}

	public void update2(SaleBill saleBill) {
		Session session = HibernateUtil.getInstance().openSession();
		session.beginTransaction();
		session.update(saleBill);
		session.getTransaction().commit();
		session.close();
	}

	@Override
	public void delete(Long id) {
		Session session = HibernateUtil.getInstance().openSession();
		session.beginTransaction();
		SaleBill bill = (SaleBill) session.get(SaleBill.class, id);
		session.delete(bill);
		session.getTransaction().commit();
		session.close();
	}

	@Override
	public SaleBill get(Long id) {
		Session session = HibernateUtil.getInstance().openSession();
		session.beginTransaction();
		SaleBill bill = (SaleBill) session.get(SaleBill.class, id);
		Hibernate.initialize(bill.getItems());
		session.getTransaction().commit();
		session.close();
		return bill;
	}
}

测试类:

public class CascadeTest {
	private ISaleBillDAO dao=new SaleBillDAOImpl();

	@Before
	public void testSave(){
		SaleBill bill=new SaleBill();
		bill.setSn("001");
		bill.setInputTime(new Date());
		SaleBillItem item1=new SaleBillItem("p1");
		SaleBillItem item2=new SaleBillItem("p2");
		SaleBillItem item3=new SaleBillItem("p3");
		item1.setBill(bill);
		item2.setBill(bill);
		item3.setBill(bill);
		bill.getItems().add(item1);
		bill.getItems().add(item2);
		bill.getItems().add(item3);
		dao.save(bill);
	}
	
	@Test
	public void testUpdate2(){
		SaleBill bill=dao.get(1L);
		SaleBillItem delete=bill.getItems().iterator().next();
		bill.getItems().remove(delete);
		dao.update(bill);
	}
	
	@Test
	public void testUpdate(){
		SaleBill bill=dao.get(1L);
		SaleBillItem item=new SaleBillItem("pnew");
		item.setBill(bill);
		bill.getItems().add(item);
		SaleBillItem item1=bill.getItems().iterator().next();
		item1.setProduct("pupdate");
		dao.update(bill);
	}
	
	@Test
	public void testDelete(){
		dao.delete(1L);
	}
}

级联的使用在现在电商和供应链领域的使用还是比较常见的,大家可以结合上述代码进行测试和学习。上述代码对象的getter、setter和tostring方法,以及ISaleBillDAO的接口还需大家自己完善。

(4)级联策略

  • 使用级联来完成SaleBillDAOImpl:(在组合关系中,一般把整体称为主对象,把部分称为子对象)

    1、在one方的集合上面,可以添加cascade属性,这个属性的意思就叫做级联;

    2、级联能根据配置的级联策略,对这个集合里面的对象自动做一些操作;

  • 级联策略:
    1、save-update:在保存或者修改主对象的时候,去级联的持久化临时的子对象,修改游离的子对象;
    2、delete:在删除主对象的时候,去级联的删除所有的子对象;
    3、all:save-update+delete
    4、delete-orphan:删除和主对象打破关系的子对象;
    5、all-delete-orphan:all+delete-orphan
    6、一般来说,对于组合关系,我们就直接使用all-delete-orphan就可以了;

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值