1.框架为我们做了哪些工作?
2.对象的三种状态
1.瞬时态
2.持久态
3.托管态
3.一级缓存: 就是session的缓存,因为hibernate要直接与数据库交互,为了减少对数据库的访问次数,
创建缓存来保存一些数据,从而提高查询效率;一级缓存是由一些了集合构建的,对应着内存中的一片区域;
一级缓存只支持OID查询,所谓OID查询:比如load,get查询
query和sqlQuery查询属于条件查询,不属于OID查询;所以一级缓存不支持query和sqlQuery查询,很鸡肋;
ps:session的增删改查是对session缓冲区的操作,不直接对数据库操作,对数据库的操作时提交时,框架把
一级缓存与快照做对比,如果不一致则更新,如果一致则不更新,所以session对数据库的操作其实是:快照和提交
共同作用的结果;
4.并发时,如果从缓存中获得数据可能不是最新的;
5.set集合的元素需要提供比价方法吗?
6.
1.级联删除是删除所有
2.孤值删除是从一方发起,删除多方的一部分;(set中remove)
7. 映射配置文件, 代码中的管理, 代码中crud操作 , 一级缓存 ,数据库中数据 它们之间关系总结;
几个辅助性结论:
1.级联解决的问题:
1.级联添加:(保存时)解决了持久态对瞬时态的引用问题
2.级联删除(删除时)一方 级联删除时会触发 多方的删除操作,多方有外键维护权,所以多方在删除的时候可以将外键删除;
也就是说解决了:一方删除时由于多方作为外键维护方,所以无法触发外键删除,进而无法完成删除的问题;
(数据库的完整性要求你不能删除一个与其他数据有关系的数据)
3.孤值删除(orphanRemoval=true)解决从一方移除多方:
//删除客户中的订单孤值
customer.getOrder().remove(order);
这样既可以删除单个订单(当然也包含它的外键),又不影响客户;
2.
<set name="order" >
<key column="fc_id"></key>
<one-to-many class="com.itheima.domain.Order" />
</set>
这个配置是为了搭建 '一方' 找到 '多方' 的桥梁;
3.
<many-to-one name="customer" class="com.itheima.domain.Customer"column="fc_id"/>
这个配置是为了搭建 '多方' 找到 '一方' 的桥梁;
这个配置是必须要配置的项,因为多方的表要通过这个配置找到'一方'的类,
然后通过'一方' 的映射配置找到'一方'的表;进而引用'一方' 的主键作为外键,完成表的创建;
4.配置文件是外键维护的桥梁,要维护外键必须在java代码中体现;
5.
8.关于一对多关系中映射配置文件的分析:
1. 一对多关系中
1.在配置中要双向级联---->可以通过任意一方操作另一方;
2.在java代码中要单向关联---->可以尽量减少资源浪费;
2. 在hibernate中 "类" 与 "表" 是强相关的,所以一旦出现了全类名,那么我们就可以认为此时
建立了一个与表的关联;
在映射配置文件中:
1. 我们看到在 <one-to-many> 标签中配置了"多方"的全类名,那么我们认为,此时建立
了与"多方"表的关联
2. 同样,在<many-to-one>标签中,配置了"一方"的全类名,那么我们认为,此时建立了与"一方"
表的关联;
3. 关于外键维护,
只要在映射配置文件中,配置了另一方,那么就有了对另一方的引用,也就有了外键维护的权利与责任;
只要没有放弃外键维护权利,默认都有这个权利,那么在默认情况下,如果在java代码中
如果 A关联了B 那么 A 会去维护外键, 如果 B 也关联了 A ,那么 B 也会去维护外键;
简而言之:在映射配置文件 hbm.xml中配置不配置 另一方,决定是否有外键维护权利和责任,
在java代码中关联不关联另一方,决定了是否有能力维护外键;
另外说明一点:在一对多关系中,"一方"和"多方"维护外键的战场都在 多方的表中;
在多对多关系中, 两个多方维护外键的战场都在另外的表中,并且这个另外的
表还不是同一张表,也就是说会各自维护一张另外的表,所以如果不加控制,会
出现两张外键的表,再加上两张"多方"的表,会出现四张表,所以在多对多关系
中一定要让其中一个放弃外键维护;
4. cascade 与 inverse 有什么区别?
确切说这俩没啥区别,也没啥联系,如果一定要扯到一块儿,那就是他们的操作用了同一个"桥"
接下来我详细解释一下: 在hibernate中有"三件套" 类 映射文件 表 ,映射文件建立了类与表之间的
的强相关,当然这个类 和 表 是 属性与字段对应的; 然而,这只是刚刚开始,在以后的学习中,我们必然
要面对一个问题,那就是 表 与 表 之间的引用关系, 一对一 , 一对多, 多对多 就是这些关系的典型
代表, 这些关系该怎么体现呢? 在类中直接建立相关字段 ,在映射文件中就有说道了: 如果说在 hbm.xml
配置了 这种关系 这意味着, 搭起了 一个类和另一个结构不相关的表之间的桥梁, 这个桥梁 搭起来的
关键不是 hbm.xml文件本事,而是 映射文件中的标签: <one-to-many> ,<many-to-one>, <many-to-many>
在这个"桥"上 ,做着两件事情:
1.外键维护, 当这个"桥" 一旦建立,外键维护默认双方都有维护外键的权利和义务,
如果要放弃,就要 inverse=true ;
2.级联操作 ,当这个"桥"一旦建立,级联操作默认是什么都没有,需要手动设置 save-update ,delete,
delete-ophan ,all, all-delete-ophan;
至此,已经说明了 cascade 与 inverse 之间的区别; 同在一个"桥"上走,一个默认做事情,一个默认不做事情;
5. 关于hibernate中映射文件中 <many-to-one> 的进一步理解:
<many-to-one> 这个标签是在多方对一方时,hbm.xml文件中出现的, 这个配置的结果
是会在多方表中建立外键,外键的数据来源是一方的主键,以上是结果; 我们来说说原因:其
实 <many-to-one> 这个标签设计的时候就有两方面考虑:
基本共识:我们在配置Order类的 hbm.xml文件时,我们会指明Order的全类名,并指明表名,
这意味着类与表关联了,我们在 <many-to-one> 中配置customer属性时也是指明了全类名,
这个时候其实这个customer也与 Customer类对应的表关联了; 也就是Order类关联了t_Order表,
它的属性customer 关联了t_Customer表; 有了这个基本共识,我们来分析一下两种情况:
1. 关联存储时: 在存储时,如果在java代码中 order对象关联了customer对象,因为他们各自
代表着各自表中的数据,所以意味着,两张表中的数据产生了关系,这个关系该怎么体现,怎么维护呢?
这个时候 <many-to-one> 隆重登场,来解决这些问题,它会取java中关联的customer对象的id存放到
多方的外键中; 这样就以外键的形式将两个表中的两条数据建立了联系;
2. 关联查询时: 在做order和customer的关联查询时,Order表中的属性customer 你可千万不能小觑
它虽然没有首字母大写,但是它也是关联着t_customer这个表的,所以你做关联查询时只需要让:
Order o 和 o.customer 进行关联就相当于是两张表的关联, 这个时候 <many-to-one> 这个标签又
一次帮我们做了一些事情:它会让customer去找到t_customer表中的id,然后和我们Order中的外键匹配作为
关联条件,而这一步完全是 <many-to-one> 的题中之义,完全不需要我们去做,它已经给我们做了;
简单总结: Order中的customer 也是引用这一张表的,另外 <many-to-one> 会在我们做关联查询时,自动
给我们添加关联条件; 在多对多时情况可能不尽相同,但道理是一致的,可以同样分析;