Hibernate cascade
1. 域模型与元数据
域模型:创建实体的及其属性的概念模型叫域模型
元数据选项:Hibernate持久化类及其属性与数据库表和列关联的方法
2. 映射持久化
- 细粒度域模型:hibernate支持细粒度的富域模型,这是使用POJO的原因,简单来说,细粒度意味着类比表要多
- 实体和值类型:@Entity和@Id注解映射一个持久化类,实体属性映射响应的值类型
3. 级联状态
如果可以跨越到另一个实体的关联来级联实体状态的状态变更,就只需要较少的代码来管理关系。细粒度控制有时对于表达关联实体之间的依赖性是必须的,JPA中用于此的机制是cascade的选项。
3.1 CascadeType.Persist
级联选项要用于想要传递的每个操作,因此要将CascadeType.PERSIST用于EntityManager#persist()操作。可以在简化item和bid保存它们的代码。
@Entity
public class Item {
@Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id;
protected String name;
@OneToMany(mappedBy = "item", cascade = CascadeType.PERSIST)
protected Set<Bid> bids = new HashSet<>();
// ...
}
@Entity
public class Bid {
@Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id;
@ManyToOne(optional = false, fetch = FetchType.LAZY)
protected Item item;
}
//持久化
EntityManager em = JPA.createEntityManager();
Item someItem = new Item("Some Item");
em.persist(someItem); // Saves the bids automatically (later, at flush time)
Bid someBid = new Bid(new BigDecimal("123.00"), someItem);
someItem.getBids().add(someBid);
Bid secondBid = new Bid(new BigDecimal("456.00"), someItem);
someItem.getBids().add(secondBid);
tx.commit(); // Dirty checking, SQL execution
em.close();
在提交时,Hibernate会检查管理/持久化的Item实例并检查bids集合,之后会从内部在每个引用的Bid实例上调用persist()并且保存它们。
3.2 级联删除
在当前级联选项中,首先要移除Bid,在移除所有者Item,在@OneToMany注解上启用级联选项CascadeType.REMOVE后,持久化引擎可以自动移除关联的实体实例
em = JPA.createEntityManager();
Item item = em.find(Item.class, ITEM_ID);
assertEquals(item.getBids().size(), 2);
for (Bid bid : item.getBids()) {
em.remove(bid);
}
em.remove(item);
//启用CascadeType.REMOVE后
Item item = em.find(Item.class, ITEM_ID);
em.remove(item);
删除需要加载该集合,因为每个Bid都是独立的实体实例,并且必须经历常规的生命周期。这一删除过程是低效的
3.3 级联合并(新增或修改)
CascadeType.MERGE:若Bid属性修改了,那么Item对象保存时同时修改items里的对象,对应EntityManager的merge方法 。
3.4 级联刷新
CascadeType.REFRESH:获取Item对象里也同时也重新获取最新的Bid的对象。对应EntityManager的refresh(object)方法有效。即会重新查询数据库里的最新数据。
4. 总结
新增和删除在项目中有部分使用场景,在删除时可以简化较多代码,但是数据关系复杂后带来的是数据量较大时的效率问题,关联关系会在数据库生成外键影响效率,有一个先从数据库获取数据,之后才能更新数据库数据,效率较低,要解决这里问题一个是深入研究Hibernate的内部机制提高效率,另一个是转向mybatis,提高灵活性。
上一篇: Android仿IOS ViewPager滑动进度条
下一篇: shell脚本游戏之:剪刀石头布