这段时间本人利用空闲时间解读了一下Hibernate3的源码,饶有收获,愿与大家共享。
废话不多说,首先我们先对Hibernate有一个大致的印象
l 设计模式Hibernate=监听器,实际上是回调
l Hibernate3支持拦截器
Hibernate配置方面的大原则:
l bhn.xml文件所有配置都是描述本实体,除了cascade描述级联,即如何将本实体的操作(增删查改)传递给关联方。
l inverse属性表示本实体是否拥有主动权,在一条cascade链路传递过程中,当出现inverse=false表示不再返回原cascade链路,而是从此处重新开始链路。inverse只有在非many方才有,也就是many-to-many或者one-to-many的set,List等。
下面是注明inverse=true与inverse=false的cascade链路的区别:
说明:若关联属性inverse=true,操作的结果将是校对A的属性所生成的sql;若关联属性inverse=false,结果将是丢弃先前A的操作,而转向对B的属性的校验所生成的sql;如果B中的属性也关联着inverse=false,则仍丢弃B继续新开启链路,直至没有关联方为inervse=false。不必担心,关联着的双方只有一方拥有inverse属性,所以不会一直传递下去。还有,丢弃了先前的操作不等于之前的对象操作无效,其效果相当于,原先的session.save(A),变成了session(A.B)而在B校对属性时总会找回A对象的。
测试用例:(暂不考虑inverse=false)
测试1:save()一个实体对象操作,预计insert发生在拥有外键方的表,拥有外键方的表是一对多中的多方。
结论1:如果实体对象的外键属性为null,表示不会产生关联,可直接生成sql;如果外键属性不为空,根据配置中的cascade去做关联。如果cascade=all则生成此表的insert和关联表update的sql,也就是说此时要求关联属性的主键id不能为null;如果cascade=save-update则生成此表的insert和关联表的insert/update的sql(关键属性的主键为null为insert,否则为update)。
见下图:
举例说明:
---------PO类:A中有B类型的关联属性
class A{
private int id;
private B b;
}
class B{
private int id;
private String str;
}
---------调用处关键代码:
A a=new A();//待操作的实体对象
B b=new B();//关联属性
a.setB(b);//设置关联属性
//----
//a.setId(1);//save()操作不允许预定一个id,hibernate的Id必须使用配置中的方式生成
//a.setB(null);//关联属性为null
//----
b.setId(1);/*关联属性的主键有值。只有cascade链在B对象校验为update操作才有效,也就是说A.bhn.xml中B
*的级联设为cascade=save-update。*/