实体关联关系映射:

http://jinnianshilongnian.iteye.com/blog/1522591

单向
  定义:不知道另一端什么情况,获取一端另一端自动获取,因为单向,你不知道另一侧是什么。
  如 class A{ B b;}
  class B{ }
  只能从A导航到B,不能从B导航到A
  关系维护:另一端维护,如B维护
双向
  定义:知道另一端(两个单向),从一端获取另一端,从另一端也能获取一端
  如 class A{ B b;}
  class B{ A a;}
  只能从A导航到B,也能从B导航到A
  关系维护:两端,对关联的一侧所作的改变,会立即影响到另一侧

关联的多样性:
  从一侧看是多对一,从另一侧看是一对多
  另外还有一对一、多对多

EJB CMP:天生双向,对关联的一侧所作的改变,会立即影响到另一侧,
如userGeneral.set(user),则自动调用user.setUserGeneral(userGeneral)
Hibernate、JPA:天生单向,两侧关系的维护是不同的关联,必须手工维护
如userGeneral.set(user),则需要手工调用user.setUserGeneral(userGeneral)。

5.2.2.3、一对一主键关系映射(非延迟抓取)

配置1(UserModel.hbm.xml)

Java代码  
  1. <one-to-one name="userGeneral" cascade="all"/>   

配置2(UserGeneralModel.hbm.xml)

Java代码  
  1. <id name="uuid">  
  2. <generator class="foreign">  
  3.         <param name="property">user</param>  
  4.     </generator>  
  5. </id>  
  6. <one-to-one name="user"   
  7.  class="cn.javass.h3test.model.UserModel"/>  
  8.           

关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。

测试:保存对象,只需保存user,自动级联保存用户信息Model

Java代码  
  1. UserModel user = new UserModel();  
  2. user.setName("昵称");  
  3. UserGeneralModel userGeneral = new UserGeneralModel();  
  4. userGeneral.setRealname("真实姓名");  
  5. userGeneral.setUser(user);  
  6. user.setUserGeneral(userGeneral);  
  7. session.save(user);  
  8. //若没有cascade="all",这句必须  
  9. //session.save(userGeneral);  

1、一对一必须手工维护双向关系。

2cascade="all":表示保存user时自动保存userGeneral,否则还需要一条saveuserGeneral

3constrained:添加把userGeneral表的主键映射到user主键的外键约束

5.2.2.4、一对多关系映射(父/子关系映射)

配置1(UserModel.hbm.xml)

Java代码  
  1. <set name="farms" cascade="all">  
  2. <key column="fk_user_id"/>  
  3.     <one-to-many class="cn.javass.h3test.model.FarmModel"/>  
  4. </set>   

配置2(FarmModel.hbm.xml) 

Java代码  
  1. <many-to-one name="user" column="fk_user_id"   
  2. class="cn.javass.h3test.model.UserModel">  
  3.              

测试:保存对象,只需保存user,自动级联保存用户信息Model

Java代码  
  1. UserModel user = new UserModel();  
  2. user.setName("昵称");  
  3. UserGeneralModel userGeneral = new UserGeneralModel();  
  4. userGeneral.setRealname("真实姓名");  
  5. userGeneral.setUser(user);  
  6. user.setUserGeneral(userGeneral);  
  7. FarmModel farm = new FarmModel();  
  8. farm.setName("farm1");  
  9. farm.setUser(user);  
  10. user.getFarms().add(farm);  
  11. //session.save(farm);//若没有cascade=all的话需要这条语句  
  12. session.save(user);   

以上配置有问题: 

Java代码  
  1. insert into TBL_USER (name, age, province, city, street, uuid) values (?, ?, ?, ?, ?, ?)  
  2.   
  3. insert into TBL_USER_GENERAL (realname, gender, birthday, weight, height, uuid) values (?, ?, ?, ?, ?, ?)  
  4.   
  5. insert into TBL_FARM (name, fk_user_id, uuid) values (?, ?, ?)  
  6.   
  7. update TBL_FARM set fk_user_id=? where uuid=?  

 1、持久化user(UserModel)

 2、持久化user的一对一关系,即userGeneral(UserGeneralModel);

 3、持久化user的一对多关系,即farms(Set<FarmModel>)

3.1、首先发现farmTO,级联save(因为在这可能是POPO的话就应该update,而不是save)

 3.2、其次发现farmfarms集合中,因此需要更新外键(fk_user_id,即执行“update TBL_FARM set fk_user_id=? where uuid=? “。

解决这个问题:

       告诉Hibernate应该只有一端来维护关系(外键),另一端不维护;通过指定<set>端的inverse=”true”,表示关系应该由farm端维护。即更新外键(fk_user_id)将由farm端维护。

配置修改(UserModel.hbm.xml)

Java代码  
  1. <set name="farms" cascade="all" inverse="true">  
  2. <key column="fk_user_id"/>  
  3.     <one-to-many class="cn.javass.h3test.model.FarmModel"/>  
  4. </set>  

再测试:保存对象,只需保存user,自动级联保存用户信息Model

Java代码  
  1. UserModel user = new UserModel();  
  2. user.setName("昵称");  
  3. UserGeneralModel userGeneral = new UserGeneralModel();  
  4. userGeneral.setRealname("真实姓名");  
  5. userGeneral.setUser(user);  
  6. user.setUserGeneral(userGeneral);  
  7.   
  8. FarmModel farm = new FarmModel();  
  9. farm.setName("farm1");  
  10. farm.setUser(user);  
  11. user.getFarms().add(farm);  
  12.   
  13. //session.save(farm);//若没有cascade=all的话需要这条语句  
  14. session.save(user);  

更新外键,需要修改FarmModel的外键并update

Java代码  
  1. insert into TBL_USER (name, age, province, city, street, uuid) values (?, ?, ?, ?, ?, ?)  
  2.   
  3. insert into TBL_USER_GENERAL (realname, gender, birthday, weight, height, uuid) values (?, ?, ?, ?, ?, ?)  
  4.   
  5. insert into TBL_FARM (name, fk_user_id, uuid) values (?, ?, ?)  

级联删除

1、当删除user时自动删除user下的farm

Java代码  
  1. user = (UserModel) session.get(UserModel.class, 1);  
  2. session.delete(user);  

结果:

Java代码  
  1. Hibernate: delete from TBL_USER_GENERAL where uuid=?  
  2. Hibernate: delete from TBL_FARM where uuid=?  
  3. Hibernate: delete from TBL_USER where uuid=?  

2、删除user中的farms的一个元素

Java代码  
  1. UserModel user =   
  2. (UserModel) session.get(UserModel.class, 118);  
  3. FarmModel farm = (FarmModel) user.getFarms().toArray()[user.getFarms().size() - 1];  
  4. user.getFarms().remove(farm);//1.必须先从集合删除  
  5. session.delete(farm);//2.然后才能删除  

结果:

Java代码  
  1. Hibernate: delete from TBL_FARM where uuid=?  

如果将子对象从集合中移除,实际上我们是想删除它。要实现这种要求,就必须使用cascade="all-delete-orphan"。无需再调用session.delete(farm)

 

5.2.2.5、多对多关系映射:不用

为什么不使用多对多:当添加新字段时给谁?

那实际项目如何用:拆成两个一对多。

原文地址:https://www.cnblogs.com/a757956132/p/4019352.html