Hibernate一级缓存(线程级别缓存,session缓存)
缓存:使用一级缓存的目的是为了减少对数据库的访问次数,从而提升hibernate的执行效率;(当执行一次查询操作的时候,执行第二次查询操作,先检查缓存中是否有数据,如果有数据就不查询数据库,直接从缓存中获取数据);
Hibernate的一级缓存由Session提供,只存在于Session的生命周期中,当应用程序调用Session接口的save(),update(),saveOrupDate(),get(),load()或者Query和Criteria实例的list(),iterate()等方法时,如果Session缓存中没有相应的对象,hibernate就会把对象加入到一级缓存中,当session关闭时,该Session所管理的一级缓存也会立即被清除;
session缓存(一级缓存):session对象中存在的缓存。缓存中存放的是(持久化)对象。
opensession();一级缓存生命周期开始
session.close();一级缓存生命周期结束
步骤一 :证明session缓存的存在
两次执行从数据库中查询id为1的对象,第一次从数据库中取出Student对象,并将此对象存入session缓存中,第二次查询时,直接从session缓存中提出已有的Student对象。
试图比较两次对象,其返回结果为true,证明一级缓存确实存在。
一级缓存是以map形式存在的,Map<串行化,Object>。
session缓存中的快照:一级缓存,对象快照,数据库状态改变,快照随时更新。
1.update(快照的存在)
(1).打印sql语句
Student stu=new Student();//瞬时状态
stu.setSname("zl");//游离状态
stu.setSno(2);//游离状态 //与session关联的id不允许修改 ,
stu.setSgrade(100); //游离状态
session.update(stu);
(2)不打印sql语句
Student stu=(Student)session.get(Student.class,1);
session.update(stu)
存在数据库查询时才存在快照,否则不存在快照。
Hibernate三种状态
hibernate 规定三种状态:瞬时态、持久态、脱管态
对象状态
瞬时态|临时态:transient,session没有缓存对象,数据库也没有对应记录。
1.与Hibernate没有产生关联
2.没有与数据库记录产生关联(与数据库中的id没有对应)
OID特点:没有值
持久态:persistent,session缓存对象,数据库最终会有记录。(事务没有提交)
持久化状态:本质是存在缓存中的对象,就是持久化状态。
1.Hibernate有关联
2.对象有id
OID特点:有值
托管态|游离态:detached,session没有缓存对象,数据库有记录。
1.没有与Hibernate产生关联
2.对象有id
OID特点:有值
Session的细节问题:
1.保存对象时使用save方法,保存对象时也可以使用persist方法
persist方法来自于JPA接口,而save方法来自于Hibernate
2.HQL语句批量查询时,查询结果是否进入缓存?HQL查询是否使用一级缓存?SQL查询结果会放入一级缓存中吗?
HQL的查询结果会进入缓存中。
HQL不会使用一级缓存。
SQL查询如果把查询结果封装到对象中,对象会放入一级缓存中。如果没有将查询结果封装到对象中,对象不会放入一级缓存。
criteria会将查询结果放入一级缓存中,查询不会使用一级缓存。
Session中的其他API(了解)
session.clear();清空session;
session.close();关闭session;
session.get(Class,Id);获取数据中的对象
session.refresh();/session.refresh(s1); 强制刷新session中的对象(可解决与数据库中数据不同步的问题)/将缓存对象与数据库中数据同步
session.flush();对比快照并提交缓存对象
session.saveOrupdate();//可以同时完成保存或更新操作,
1.非自然主键情况下,主键为空=>save,主键不空=>update;
2.自然主键情况下(assigned),主键为空,报错,因为无论是save还是update,都必须指定id;
主键有值,先根据id,查询数据库,数据库中存在,执行update,不存在,执行insert
参考:https://blog.csdn.net/fg2006/article/details/6436517