Hibernate--关联关系

关联关系映射:
表与表之间的关系:
一对多、多对多、一对一
对象之间的关系:
一对多 :A 和B

class A{
   //一对多
   private 容器<B> ...;     容器:数组Array、List、Set、Map 等,建议:set集合(无序、不重复)
}
class B{
   //多对一
   private A a;
}

多对多

class A{
   private Set<B> setB...
}
class B{
   private Set<A> setA...
}

一对一

class A{
   private B b;
}
class B{
   private A a;
}

例如:一对多:
分析:
对象:客户:public class Customer {
 private Integer cid;
 private String cname;
 //一对多:一个客户 拥有 【多个订单】
 // * 使用容器为set:无序、不重复
 private Set<Order> orderSet = new HashSet<Order>();
映射文件:
 <class name="cn.xxx.b_one_to_many.Customer" table="t_customer">
  <id name="cid">
   <generator class="native"></generator>
  </id>
  <property name="cname"></property>
  <!-- 一对多:一个客户 拥有 【多个订单】
   1.确定集合,并确定属性
   2.确定从表中外键的名称
   3.确定集合存放对象关系及类型
  -->
  <set name="orderSet">
   <key column="customer_id"></key>
   <one-to-many class="cn.xxx.b_one_to_many.Order"/>
  </set>
 </class>
对象:订单
public class Order {
 
 private Integer xid;
 private String price;
 
 //多对一:多个订单(当前订单) 属于 【一个客户】
 private Customer customer;
映射文件: <class name="cn.xxx.b_one_to_many.Order" table="t_order">
  <id name="xid">
   <generator class="native"></generator>
  </id>
  <property name="price"></property> 
  <!-- 多对一:多个订单(当前订单) 属于 【一个客户】
   1.确定属性
   2.确定对用类型
   3.确定当前对象Order,对应的表中外键名称
  -->
  <many-to-one name="customer" class="cn.xxx.b_one_to_many.Customer" column="customer_id">
         </many-to-one>
  
 </class>
注:如果想要看到两张表所呈现出来的关系,可以通过ER图得到。
    持久态对象 关联的对象 也必须是持久态,否则将抛异常。
    在进行双向关联时,只需要从表进行关联就可以了,因为从表会主动跟新外键,如果再让柱表进行关联,那么主表的对外键的更新就多余了
 所以要在主表的配置文件中进行对外键的放权操作【inverse="true"】

级联操作:cascade
 A和B存在关联关系。例如:customer.getOrderSet() ,当对A进行相应的操作时,并以对B也操作。
级联保存或更新 --> 在保存客户customer时,一并让hibernate自动的保存订单order需在Customer.hbm.xml <set cascade="save-update" >
级联删除:
  查询客户、删除客户,默认情况:先将order 外键更新null,再删除客户。结果:客户没有,订单有(外键null)
  // * 级联删除:在删除客户的同时,一并将订单删除了。结果:客户没有,订单也没有,需在Customer.hbm.xml <set cascade="delete">
多个配置项之间使用逗号分隔
孤儿删除:
 一对多,存在一个父子关系。一方父,多方子。从表不能添加,主表不存在数据。主表不能删除,从表已经使用的数据。
  查询客户、查询订单,解除客户和订单关联关系
  // * 默认情况:更新从表外键为null。结果:客户存在,订单存在(外键null), 孤儿删除:当客户和订单解除关系时,一并删除订单。结果:客户存在,订单删除
级联总结:
 save-update,级联保存或更新,在保存A时,一并保存B。
 delete,级联删除,在删除A时,一并删除B。
 delete-orphan,孤儿删除,解除关系时,一并删除B。
 all ,save-update和delete组合。
 all-delete-orphan ,三个组合。

多对多:
将一个多对多拆分成两个一对多,提供中间表(从表),与另外两个主表形成主外键关系,中间表提供两个字段,两个字段分别对应主表的外键。将两个外键合并在一起形成联合主键。
映射文件: <class name="cn.xxx.c_many_to_many.Student" table="t_student">
  <id name="sid">
   <generator class="native"></generator>
  </id>
  <property name="sname"></property>
  <!-- 多对多:多个学生 可以学习【不同的课程】
   1.确定容器,及对象
   2.确定中间表的表名
   3.自己(当前对象)在中间表中的外键的名称
   4.确定关系、关联对象类型、关联对象在中间表的外键的名称
  -->
  <set name="courseSet" table="t_student_course">
   <key column="student_id"></key>【此处的key为中间表中的sid主键】
   <many-to-many class="cn.xxx.c_many_to_many.Course" column="course_id"【此处的key为中间表的cid主键】></many-to-many>
  </set>
 </class>
 一对多:inverse="true" 主表放弃对从表外键维护。(一个字段 update)
 多对多:inverse="true" 主表放弃对中间表记录维护。(一条记录 insert)
双向级联删除:
在多表中配置cascade=“delete”
一方放权:cascade=“delete” inverse=“true”

检索方式:
 立即检索:进行查询时,立即查询所有需要。
 延迟检索:进行查询时,直到需要数据时,才进行查询。
get():立即检索,方法一调用马上执行select语句。如果数据库没有数据,将返回null。
load():默认进行延迟检索,方法一调用暂时不执行select语句,直到需要除OID之外的数据时才进行查询。如果数据库没有数据,将抛异常
检索策略:
 类级别检索:除OID之外,其他字段延迟。
 关联级别检索:当前对象 关联 的另一个对象 是否延迟。
类级别:
Customer.hbm.xml  <class name="" table="" lazy="true | false">
 lazy="true" 通过load()进行查询时,将进行延迟检索。
 lazy="false"通过load()进行查询时,将进行立即检索。


 

猜你喜欢

转载自jackpot1234.iteye.com/blog/2317876