黑马程序员技术交流社区

标题: 【石家庄校区】学习笔记-Hibernate(4) [打印本页]

作者: htb52110    时间: 2018-1-15 19:18
标题: 【石家庄校区】学习笔记-Hibernate(4)
本帖最后由 htb52110 于 2018-1-15 19:29 编辑

7、Hibernate一级缓存
7.1、概念
Hibernate的一级缓存就是指session缓存。
actionQueue它是一个行动队列,它主要记录crud操作的相关信息
persistenceContext它是持久化上下文,它其实是真正缓存。
在session中定义了一系列的集合来存储数据,它们构成session缓存。
只要session没有关闭,它就会一直存在。
当我们通过hibernate中的session提供的一些API例如 save  get  update等进行操作时,就会将持久化对象保存到session中,当下一次在去查询缓存中具有的对象(OID值来判断),就不会去从数据库查询,而是直接从缓存中获取。
Hibernate的一级缓存存在的目的就是为了减少对数据库访问。
在hibernate中还有一个二级缓存,它是SessionFactory级别缓存
7.2、持久化对象具有自动更新数据库的能力
原因:
7.3、一级缓存常用API
一级缓存特点:
a、当我们通过session的save,update saveOrupdate进行操作时,如果一级缓存中没有对象,会将这些对象从数据库中查询到,存储到一级缓存。
b、当我们通过session的load,get,Query的list等方法进行操作时,会先判断一级缓存中是否存在,如果没有才会从数据库获取,并且将查询的数据存储到一级缓存中。
c、当调用session的close方法时,session缓存清空。
常用的操作:
flush
修改一级缓存数据,针对内存操作,需要在session执行flush操作时,将缓存变化同步在数据库,而只有在缓存数据与快照区不一致的时候,才会生成update语句。
clear
清除所有对象的一级缓存,对对象所做的修改,全部都没有了,跟当初的快照一样。.
evict
清除一级缓存指定对象。将指定的持久化对象从缓存中清除,释放对象所占用的内存资源,指定对象从持久化状态变为脱管状态,从而成为游离对象。
                      refresh
重新查询数据库,更新快照和一级缓存。
7.4、Hibernate常用API-Session补充
7.4.1、update
udpate操作它主要是针对于脱管对象,持久对象具有自动更新能力。
Update操作时,如果对象是一个脱管对象,可以操作,它会将脱管对象转换成持久对象在操作
       如果在session中出现相同的oid两个对象,会产生异常
脱管对象的oid如果在数据表中不存在,会报异常

注意:在操作中,建议我们通过持久化对象来直接修改其操作。
7.4.2、saveOrUpdate
如果对象是一个瞬时对象 --------执行save操作
如果对象是一个脱管对象---------执行update
如果是一个持久对象-------直接返回
7.4.3、delete
删除一个脱管对象,与session关联,在删除
注意:如果执行delete操作,先删除一级缓存,在删除数据库中的数据。
7.5、扩展
1.Session级别的缓存,它同session绑定。它的生命周期和session相同。Session销毁,它也同时销毁;管理一级缓存,一级缓存无法取消,用两个方法管理,clear(),evict()。
2.两个session不能共享一级缓存,因为它会伴随session的生命周期的创建和销毁;
3.Session缓存是实体级别的缓存,就是只有在查询对象级别的时候才使用,如果使用HQL和SQL是查询属性级别的,是不使用一级缓存的!切记!!!!
4.iterate查询使用缓存,会发出查询Id的SQL和HQL语句,但不会发出查实体的,它查询完会把相应的实体放到缓存里边,一些实体查询如果缓存里边有,就从缓存中查询,但还是会发出查询id的SQL和HQL语句。如果缓存中没有它会数据库中查询,然后将查询到的实体一个一个放到缓存中去,所以会有N+1问题出现。
每一个Hibernate Session实例和一个数据库事务绑定,就是说,每执行一个数据库事务(操作),都应该先创建一个新的Hibernate Session实例。
如果事务执行中出现异常,应该撤消事务.不论事务执行成功与否,最后都应该调用Session的close()方法,从而释放Hibernate Session实例占用的资源。
7.6、缓存区和快照区
7.6.1、缓存区
就比如我们在调用hibernate中的调用方法查询到数据库并拿到了数据库对象的时候,hibernate会首先把查询的数据对象放到一级缓存和快照区中,但是当我们对这个对象我们查询的数据对象进行修改的时候(当然对象必须在存在于Hibernate一级缓存中且session没有关闭的情况下。)我们修改的只是修改缓存区中的内容,而不会修改快照区的内容,这是一个最重要的机制,但是在提交事务的时候hibernate框架会自动的去拿缓存区和快照区的内容进行对比,如果快照区与缓存区的内容是一致的,那就不会去更新到数据库,但是如果是不一样的那就会自动的更新到数据库。这种机制又是提高Hibernate框架的执行效率。
7.6.2、快照区
快照区,什么是快照区,其实可以这么理解快照区,快照区就是存放照片的,只不过是这个照片有点独特,那就是这个照片是从数据库中拿到的数据的照片。快照区所做的事就是在数据放入缓存区的同时对数据进行“拍照”对其进行记录。以便在以后缓存区中的数据修改的时候进行对比看数据是否发生了变化,如果变化那就更新到数据库,其实到这里也就容易理解为什么我们在修改对象的时候缓存区中的数据会发生相应的改变而快照区不会发生改变了。是因为快照区中存的是“照片”嘛。照片的内容我们是改变不了的,不是吗?
7.7、Session手动控制缓存
在hibernate中也为 我们提供了手动控制缓存的机制,具体如下
Always        每次查询时,session都会flush
Auto        有些查询时,session会默认flush,例如commit,session.flush
Commit        在事务提交的时候
Manual        只有手动调用sessionflush才会刷出

8、Hibernate关联映射-数据对象三种关系介绍
Hibernate框架基于ORM设计思想,它将关系型数据库中的表与我们java中的类进行映射,一个对象就对应着表中的一条记录,而表中的字段对应着类中的属性。
数据库中表与表之间存在着三种关系,也就是系统设计中的三种实体关系。
8.1、一对一
原则有两种:
a、唯一外键对应:在任意一方添加外键来描述对应关系
b、主键对应:一方的主键作为另一方的主键

8.2、一对多
客户与订单之间一对多关系(多对一)
建表原则:在多的一方添加外键来描述关联关系
8.3、多对多
例如学生与老师
建表原则:通过一张中间表来描述其对应关系
8.4、扩展
8.4.1、词汇解释
  关系:事物之间相互作用、相互联系的状态。范围最大。
  联系:在关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。
  关联:表示对象之间的关系,既有数量性,又有方向性;动词:将对象之间通过某种方式联系起来。
  映射:这里指java对象和数据库表的一种对应关系。动词:形成这种对应关系。
  级联:有关系的双方中操作一方,另一方也将采取一些动作。
8.4.2、关联联系的种类
在不考虑关联的方向前提下,联系就是关系数据库中表示实体与实体之间的联系,1:1,1:n,m:n。
一对一联系(1:1):如用户和身份证、一夫一妻
一对多联系(1:n):如班级和学生,客户和订单
  多对多联系(m:n):如学生和选课
8.4.3、关联的方向
关联关系的方向可分为单向关联和双向关联。
双向关联的方向其实就不重要了,因为通过任一一方都可以维护彼此的关系。也就是说:在双向关联中一对多和多对一都是一样的。

作者: Yin灬Yan    时间: 2018-1-17 12:38
我来占层楼啊   




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2