yuyee

hibernate简单知识

Session接口几个基本操作 

    • 1.get()方法:先确认该ID对应的数据是否存在,先经过session缓存,再二级缓存,之后是数据库,如果不存在,返回null
    • 2.load()方法:hibernate会默认你是存在的,他会放心的使用代理类在延迟加载数据,当用到他的其他属性时,就会跑去数据库中查询,如果不在,抛异常
    • 3.list()方法:去数据库读取数据,填充缓存,
    • 4.iterator()方法:先去数据库select id from table,之后到缓存中查找,如果不存在,出现N+1问题.

缓存 

    • 1.一级缓存:session级缓存,如果session关闭,,清空,释放内存
 
    • 2.二级缓存:SessionFactory级别的全局缓存,它底下可以使用不同的缓存类库,比如ehcache、oscache等,需要设置hibernate.cache.provider_class
    • 缓存可以看成是个hastable,典型的空间换时间,一般在读写比高的情况下使用

Hibernate中使用二级缓存 

    • Class的缓存  
      对于一条记录,也就是一个PO来说,是根据ID来找的,缓存的key就是ID,value是POJO。无论list,load还是iterate,只要读出一个对象,都会填充缓存。但是list不会使用缓存,而iterate会先取数据库select id出来,然后一个id一个id的load,如果在缓存里面有,就从缓存取,没有的话就去数据库load。假设是读写缓存,需要设置:  
      <cache usage=“read-write”/><缓存并发策略>
    • 使用二级缓存第三方插件ehcache.jar来实现,在hibernate.cfg.xml中配置
    • 如下图:是我测试TestDAO工程的hiberante.cfg.xml配置

Hiberante.cfg.xml

ehcache.xml配置 

    • <defaultCache  
              maxElementsInMemory=“10000” //在缓存区最大元素 默认为10000;  
              eternal=“false”  //是否永久不超时  
              timeToIdleSeconds=“120”  // :缓存数据的钝化时间,也就是在一个元素消亡之前,两次访问时间的最大时间间隔值  
              timeToLiveSeconds=“120” //从创建后存活的最长时间  
              overflowToDisk="true" //溢出到硬盘;  
              /> 
 
    • 每个存储的CLASS都要有这样的配置,如果你没配置,Hibernate会警告你,然后使用缺省的defaultCache

查询缓存  

    • 需要配置<property name="hibernate.cache.use_query_cache">true</property>
    • query.setCacheable(true);//激活查询缓存  
      query.setCacheRegion(“myCacheRegion”);//指定要使用的cacheRegion,如果不做,会使用标准的查询缓存的配置
    • 查询缓存来说,缓存的key是根据hql生成的sql,再加上参数,分页等信息
    • 重点:如果是list()方式的话,value在这里并不是整个结果集,而是查询出来的一串ID.
    • 不管是list方法还是iterate方法,第一次查询的时候,它们的查询方式和它们平时的方式是一样的,list执行一条sql,iterate执行1+N条,多出来的行为是它们填充了缓存。但是到同样条件第二次查询的时候,就都和iterate的行为一样了,根据缓存的key去缓存里面查到了value,value是一串id,然后在到class的缓存里面去一个一个的load出来。
    • 所以说,查询缓存需要打开相关类的class缓存。list和iterate方法第一次执行的时候,都是既填充查询缓存又填充class缓存的,还有一点,Class缓存的时间一定要比查询缓存长,不然还是会出现N+1问题

缓存与数据库同步 

    • hibernate在一个地方维护每个表的最后更新时间,其实也就是放在上面org.hibernate.cache. UpdateTimestampsCache所指定的缓存配置里面。 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
    •   
      当通过hibernate更新的时候,hibernate会知道这次更新影响了哪些表。然后它更新这些表的最后更新时间。每个缓存都有一个生成时间和这个缓存所查询的表,当hibernate查询一个缓存是否存在的时候,如果缓存存在,它还要取出缓存的生成时间和这个缓存所查询的表,然后去查找这些表的最后更新时间,如果有一个表在生成时间后更新过了,那么这个缓存是无效的。  
      可以看出,只要更新过一个表,那么凡是涉及到这个表的查询缓存就失效了,因此查询缓存的命中率可能会比较低。

使用二级缓存的前置条件 

    • 使用hiberante的应用对数据库具有独占访问权,既不能被第三方修改数据,因为那样缓存不知道你修改了数据,无法与数据库同步.
    • 如果自己程序里使用了JDBC来更新,不通过hiberante更新,也会出现跟数据库不同步的情况

posted on 2010-10-25 00:30 羔羊 阅读(226) 评论(0)  编辑  收藏 所属分类: orm