hibernate性能优化

来源:互联网 发布:知彼软件是干什么的 编辑:程序博客网 时间:2024/05/05 03:32

1.注意session,clear()的应用,尤其在不断分页循环的时候

   a).在一个大集合中进行遍历,遍历message,取出其中的含有敏感字样的对象。(eg.每处理50条数据,就调用session.clear());

   b).另外一种形式的内存泄漏 ; (面试题:Java有内存泄漏?  在语法级别上没有,语法级别不用回收内存,有专门的垃圾收集器自动回收;但在写程序的时候,很多情况下如果用到了一些资源,一定要回收。比如说打开了连接池,一定要记得关闭,不然在内存中一直打开了。打开文件,Java调了CC调了Windowsapi,而C没有垃圾回收器。在这种情况下就有内存泄漏);

2.1+N问题

   问题表述:在多对一的关系中,当我们需要查询多的一方对应的表的记录时,可以采用一条sql语句就能完成操作。然而,在多的一方的实体类中的@ManyToOne标注的fetch的默认值是eager,这时,hibernate除了发出查询多的一方对应的表的记录的sql语句外,还会发出n(多方记录数)条sql语句,这就是1+问题。

   eg:bbs的板块(Category),主题(topic),回复(msg)。一个板块有多个主题,而一个主题属于一个板块,则Categorytopic属于一对多的关系,在topic里设置@ManyToOne。当需要取出所有的主题时,只需要发出select * from topic一条语句就能做到。然而,hibernate会查询出每个topic所对应的Category,所以会发出1+nsql语句。

    解决的方法是:

      ①在多的一方:设置@ManyToOnefetch属性值为lasy,这种方式解决后,后面的nsql语句按需而发。

      ②在一的一方:设置@BatchSize(size=5),这样发出的sql语句减少。这个设置在一定程度上提高了效率。

      ③用join fetch,事实上Criteria用的就是这种方法。

      ④直接用session.createCriteria(Topic.class).list()取值;

3.list和iterate

    a).List的获取方式为:list<Object>list=query.list();
Iterator的获取方式为:Iterator<Object>it=query.iterate();
    b).获取数据的方式不一样,list()会直接查询数据库,iterator()会先到数据库中把ID都取出来,然后真正要遍历某个对象的时候先到缓存中找,如果找不到,以ID为条件再发一条sql到数据库,这样如果缓存中没有数据,则查询数据库的次数为n+1次;  
    c).list只查询一级缓存,而iterator会从二级缓存中查;
    d).list方法返回的对象都是实体对象,而iterator返回的是代理对象

4.一级缓存和二级缓存和查询缓存

    a).什么是缓存
可以在内存里开辟一块空间,把原来存放硬盘上面的东西,存放到内存中,将来可以直接从内存中读取,这部分叫做缓存。
    b).什么是一级缓存,session级别的缓存;
    c).什么是二级缓存,sessionFactroy级别的缓存,可以跨越session存在;
二级缓存适合使用:
i.经常被访问
ii.改动不大,不会经常被改动
iii.数量有限
    d).打开二级缓存
i.hibernate.cfg.xml设置:
<!-- 开启二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>
<!-- 开启查询缓存 -->
<property name="hibernate.cache.use_query_cache">true</property>
<!-- 二级缓存区域名的前缀 -->
<!--<property name="hibernate.cache.region_prefix">h3test</property>-->
<!-- 高速缓存提供程序 -->
<property name="hibernate.cache.region.factory_class">
net.sf.ehcache.hibernate.EhCacheRegionFactory
</property>
<!-- 指定缓存配置文件位置 -->
<property name="hibernate.cache.provider_configuration_file_resource_path">
ehcache.xml
</property>
<!-- 强制Hibernate以更人性化的格式将数据存入二级缓存 -->
<property name="hibernate.cache.use_structured_entries">true</property>

<!-- Hibernate将收集有助于性能调节的统计数据 -->
<property name="hibernate.generate_statistics">true</property>
 
 
 ii.@Cache注解
   e).load默认使用二级缓存,iterator默认使用二级缓存;
   f).list默认往二级缓存加数据,但是查询的时候不使用;
   h).缓存算法:
         i.LFU(Least Frequently Used):最近不常被使用(命中率低),一定时间段内使用次数最少的;
   ii. LRU(Least Recently Used):最近很少使用(LinkedHashMap),没有被使用时间最长的;
   iii. FIFO(First In First Out):先进先出






 

     

1 0