关联关系映射:
表与表之间的关系:
一对多、多对多、一对一
对象之间的关系:
一对多 :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()进行查询时,将进行立即检索。