Hibernate缓存学习笔记

一级缓存(在同一个Session中,缓存实体对象,生命周期与Session一致)
查询实体
  1.执行两次load,get,第二次会从缓存里取
  2.执行两次iterate
   HQL:from Student s where s.id=1
   第一次:
    首先:select student_id from t_student where student_id=1;查询出ID列表
    然后:select * from t_student where student_id=1;根据ID查询实体
   第二次:
    select student_id from t_student where student_id=1;查询出ID列表
    不会发出SQL,因为缓存里有。
  3.先save,后load或get,不会发SQL,因为save后,它会往缓存里放一份
 
查询普通属性
  1.执行两次iterate
   HQL:select s.name from Student s where s.id=1;
   第一次:select name from t_student where id=1;没有放入缓存
   第二次:select name from t_student where id=1;
缓存管理
  一级缓存是无法取消,但可以管理(session.evict(object),session.clear())
  Hibernate导入数据:因为save方法,每执行一次就会往缓存里让一份,所以可以每隔小量数据,
  先session.flush(),然后session.clear(),避免内存溢出。
  如果数据量特别大,可以采用jdbc,如果jdbc也不能满足要求,可采用数据库的专门导入工具
 
二级缓存(进程级缓存,缓存实体对象,生命周期与SessionFactory一致)
配置:1.首先到Hibernate根目录下的etc下的ehcache.xml拷贝到classpath可以搜索到的地方
    它有个默认配置选项
    <defaultCache
   maxElementsInMemory="10000"  //内存中可以存一万个对象
   eternal="false"     //这些对象在内存中不是永久有效的,与下面两个属性是互斥的
   timeToIdleSeconds="120"   //空闲的时间
   timeToLiveSeconds="120"   //缓存对象生命是多长(120秒)
   overflowToDisk="true"   //超过10000个对象时,是否要保存到磁盘上.保存路径为如下
   />
   <diskStore path="java.io.tmpdir"/>  这表示操作系统的临时路径,
   在WINDOWS上为C:\WINDOWS\temp\
    2.在Hibernate.cfg.xml中开启二级缓存将hibernate.cache.use_second_level_cache设置为true
    3.指定缓存产品提供商
    将hibernate.cache.provider_class设置为 org.hibernate.cache.OSCacheProvider
    4.在映射文件中指定缓存策略
   <cache usage="read-only"/>
   也可以在配置文件中指定<class-cache class="com.shadow.Student" usage="read-only"/>
   我个喜欢配置在配置文件中,这样查看比较方便(read-only效率最高,read-write也可以)
查询实体
  1.在两个不同的Session中,get,load,都会使用二级缓存
一级缓存与二级缓存的交互
  session.setCacheMode(CacheMode.GET | CacheMode.PUT | Cache.NORMAL)
 
查询缓存(只有query.list()使用查询缓存,query.list()也只使用查询缓存)
缓存普通属性结果集,对实体对象的结果集只缓存ID,如果当前关联的表发生的修改,那么查询缓存生命周期结束
配置:启用查询缓存 将hibernate.cache.use_query_cache设置为true
  在程序中显式的查询缓存query.setCacheable(true)
  HQL:select s.name from Student s
一.查询普通属性
  1.在同一个Session中,执行两次query.list();
   1>关闭二级缓存,关闭查询缓存,会发两次SQL
   2>关闭二级缓存,打开查询缓存,第一次会发,第二次不会发
  2.开启两个Session,分别调用query.list();
   关闭二级缓存,打开查询缓存,第一次会发,第二次不会发,查询缓存的生命周期与Session无关
  3.开启两个Session,分别调用query.iterate();
   关闭二级缓存,打开查询缓存,两次都会发,查询缓存对query.iterate()方法无效,即query.iterate()
   不使用查询缓存
二.查询实体对象
  1.开启两个Session,分别调用query.list();
   HQL:select s from Student s
   1>关闭二级缓存,关闭查询缓存,会发两次SQL
   2>关闭二级缓存,开启查询缓存,第一次会发一条SQL:select * from t_student
   第二次会发n条SQL,都是根据Id来查询,SQL:select * from t_student where id=?
   因为开启了查询缓存,对于实体对象只会缓存实体Id
   3>开启二级缓存,开启查询缓存,第一次会发,第二次不会发
  2.在同一个Session中,执行两次query.list();
   1>关闭二级缓存,关闭查询缓存,会发两次SQL,因为query.list()只存不取

你可能感兴趣的:(sql,Hibernate,jdbc,cache,配置管理)