Hibernate查询缓存全面分析
缓存分类:
◆一级缓存Session级
◆二级缓存SessionFactory级别JVM级别
Hibernate查询缓存不固定(根据生命周期来说不固定)
生命周期:
◆一级缓存是和session会话一直产生一直消失
◆二级缓存是和sessionFacotry一致
Hibernate查询缓存生命周期不固定,当数据库表发生改变的使用Hibernate查询缓存马上消失
使用方法:
◆一级缓存:这个就不用说了
◆二级缓存:首先拷贝使用Hibernate查询缓存类别.xml到classpath目录下面,然后到hibernate.cfg.xml里面配置。开启二级缓存(默认开启),定义要使用二级缓存的实体类,然后就是在程序中要显示的指定session。
使用二级缓存的类别有三种,Normal,GET,PUT默认使用的是Normal即可以写也可以读取二级缓存(这里读写是指的会话Session)
Hibernate查询缓存:首先也是到hibernate配置文件中去开启Hibernate查询缓存,然后程序中也要显示的调用方法来开启Hibernate查询缓存eg:query.setCachemodel(true);
缓存的保存对象:
◆一级缓存:缓存的是实体
◆二级缓存缓存的也是实体
Hibernate查询缓存缓存的是查询出来的实体的部分属性结果集和实体的ID(注意这里不是实体)
缓存的使用对象:
◆一级缓存:
Load(Lazy加载)使用一级缓存当load的使用首先查找把序列号去和一级缓存匹配是否有,就直接取出来如果没有就发出SQL语句。
Get也使用一级缓存。
List接口query.list()不使用一级缓存每次都要发出SQLeg:(select*fromtudent)。Iterator接口query.iterate();使用一级缓存首先是要发出一条SQL来取得ID,eg:select。idfromstudent;然后把ID拿到缓存中去匹配如果有就直接取如果没有,就要再发出SQL如果都没有将发出N+1条SQL这就是N+1问题
◆二级缓存:都使用了二级缓存
Hibernate查询缓存:看到名字顾名思义就知道是查询那么就是对List和Iterator接口起作用
但是Hibernate查询缓存对Iterator不起作用,只对List起作用。
下面我们这种介绍把二级缓存和Hibernate查询缓存结合使用
当只是用Hibernate查询缓存而关闭二级缓存的时候:
第一:如果查询的是部分属性结果集:
那么当第二次查询的时候就不会发出SQL直接从Hibernate查询缓存中取数据第二:如果查询的是实体结果集eg(fromStudent)这个HQL那么查询出来的实体,首先Hibernate查询缓存存放实体的ID,
第二次查询的时候就到Hibernate查询缓存中取出ID一条一条的到数据库查询这样将发出N条SQL造成了SQL泛滥
当都开启Hibernate查询缓存和二级缓存的时候
第一:如果查询的是部分属性结果集:这个和上面只是用Hibernate查询缓存而关闭二级缓存的时候,一致因为不涉及实体不会用到二级缓存
第二:如果查询的是实体结果集eg(fromStudent)这个HQL那么查询出来的实体,首先Hibernate查询缓存存放实体的ID,第二次查询,的时候就到Hibernate查询缓存中取出ID,拿到二级缓存区找数据,如果有数据就不会发出SQL如果都有一条SQL都不会发出直接从二级缓存中取数据。