与级联有关.hbm.xml文件中的几个属性:cascade, inverse, lazy
1. cascade: 哪些操作设置级联。none, save-update, delete, all。一般一方设置delete(级联删除,删除一方,关联的多方全部删除),多方设置save-update(级联保存和更新)
2. inverse: 是否放弃维持级联关系。只有一方需要设置,默认是false。一方一般设置成true,表示级联关系由多方维护外键。比如,一方cascade=delete,inverse=true,则一方进行删除时,先删除一方,然后根据外键关系删除多方,再由多方维护外键关系,即删除外键。若设置inverse=false,则删除一方后,一方维护外键关系,将多方的外键值设置为空,再根据外键去删除多方时会出错。
3. lazy: 延迟加载(懒加载)。lazy默认是true,表示延迟加载。只有真正使用该对象的数据时才会创建。若一方设置one-to-many时,lazy=true,则当在一个action中,要获取多方的set时,由于想要获取多方的代理对象,而多方相关的session已经关闭了,会出现异常:failed to lazily initialize a collection of role……设置lazy=false,则立即加载,不用初始化懒加载对象(代理对象),直接初始化多方对象,并获得其对象数据。不过懒加载能节约资源和空间~
代码示例:
a. 一方级联删除,多方级联保存
一方(BreedCompany)配置:
<set name="breedStaffs" inverse="true" lazy="false" cascade = "delete">
<key>
<column name="companyId" length="30" not-null="true">
</column>
</key>
<one-to-many class="org.wuxi.fudan.syfw.model.hibernate.BreedStaff" />
</set>
多方(BreedStaff)配置:
<many-to-one name="breedCompany" class="org.wuxi.fudan.syfw.model.hibernate.BreedCompany" fetch="select" cascade="save-update">
<column name="companyId" length="30" not-null="true" >
</column>
</many-to-one>
一方删除:直接delete该breedCompany对象即可,多方会根据外键级联删除所有该公司的人员,最后维护外键
多方保存:
breedStaff.setBreedCompany(userService.findBreedCompanyById(companyId));
breedStaffService.save(breedStaff);
多方先保存,然后根据breedCompany对象维护外键。
根据一方获取所有相关多方对象:直接通过一方的get方法获得多方对象的集合set
Set<BreedStaff> sets = new HashSet<BreedStaff>();
breedCompany = userService.findBreedCompanyById(companyId);
sets = breedCompany.getBreedStaffs();
b. 一方级联保存和删除
一方(BreedArea)配置:
<set name="netCages" cascade="all" lazy = "false" inverse="true">
<key>
<column name="areaId" length="30" not-null="true">
</column>
</key>
<one-to-many class="org.wuxi.fudan.syfw.model.hibernate.NetCage" />
</set>
多方(NetCage)配置:
<many-to-one name="breedArea" class="org.wuxi.fudan.syfw.model.hibernate.BreedArea" fetch="select" cascade="save-update">
<column name="areaId" length="30" not-null="true">
</column>
</many-to-one>
Set<NetCage> set = new HashSet<NetCage>();
if(netcages != null){
String[] netcage = netcages.split(",");
for(String net:netcage){
NetCage nc = new NetCage();
nc.setNetcageId(net);
nc.setBreedArea(breedArea);
set.add(nc);
}
}
breedArea.setNetCages(set); //设置网箱
breedAreaService.save(breedArea); //保存养殖区域,同时级联保存网箱信息
先设置好外键关系:
nc.setNetcageId(net);//主键 nc.setBreedArea(breedArea);//外键 set.add(nc); //一方的set
然后通过一方的save方法,先保存一方信息,再保存多方信息,最后多方维护外键关系。
一方删除:
直接通过一方的删除操作,删除一方的对象。会级联删除相关的多方信息,并维护外键。