hibernate性能优化

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

(1)在一个大集合中进行遍历,遍历msg,取出其中的含有敏感字样的对象

(2)另外一种形式的内存泄露   //Java有内存泄露么?语法上没有,但是在写程序时,打开的资源要记得关闭。比如调文件的输出流等,java调用C,C调用window的api,这是就需要进行关闭

2. 1+N问题(由于多的一方的fetch默认为lazy,所以在取多的一方的时候,会带出一的一方)

解决方案:(1)将@manytoone(fetch=FetchType.LAZY)

                    (2)使用@BatchSize注释:在一的一方的实体类上加:@Entity

                                                                                                                        @BatchSiez(size=5)

                    (3)join fetch

3.list_iterate

List-->一下子将数据库中所有的字段取出,且不能够使用session缓存(大多数的情况下使用list已经足够)

iterate-->先取id,如果有需要,再取出相关的字段,且能够使用session缓存

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

(1)一级缓存:session级缓存

(2)二级缓存:sessionFactory级缓存

在主配置文件中hibernate.cfg.xml :

<!-- 使用二级缓存 -->
<property name="hibernate.cache.use_second_level_cache">true</property>    
<!--设置缓存的类型,设置缓存的提供商-->
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
或者当hibernate与Spring整合后直接配到Spring配置文件applicationContext.xml中

<bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
     <property name="dataSource" ref="dataSource"/>
     <property name="mappingResources">
        <list>
          <value>com/lp/ecjtu/model/Employee.hbm.xml</value>
          <value>com/lp/ecjtu/model/Department.hbm.xml</value>
        </list>
     </property>
     <property name="hibernateProperties">
        <value>
        hibernate.dialect=org.hibernate.dialect.OracleDialect
        hibernate.hbm2ddl.auto=update
        hibernate.show_sql=true
        hibernate.format_sql=true    
        hibernate.cache.use_second_level_cache=true
        hibernate.cache.provider_class=org.hibernate.cache.EhCacheProvider
         hibernate.generate_statistics=true           
     </value>
    </property>
</bean>
配置 ehcache.xml

<?xml version="1.0" encoding="UTF-8"?>
<ehcache>
    <!--
        缓存到硬盘的路径
    -->
    <diskStore path="d:/ehcache"></diskStore>
    
    <!--
        默认设置
        maxElementsInMemory : 在內存中最大緩存的对象数量。
        eternal : 缓存的对象是否永远不变。
        timeToIdleSeconds :可以操作对象的时间,最大带在内存中没人操作的时间。
        timeToLiveSeconds :缓存中对象的生命周期,时间到后查询数据会从数据库中读取。
        overflowToDisk :内存满了,是否要缓存到硬盘。
    -->
    <defaultCache maxElementsInMemory="200" eternal="false" 
        timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></defaultCache>
        
    <!--
        指定缓存的对象。
        下面出现的的属性覆盖上面出现的,没出现的继承上面的。
    -->
    <cache name="com.suxiaolei.hibernate.pojos.Order" maxElementsInMemory="200" eternal="false" 
        timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></cache>

</ehcache>

使用二级缓存需要在实体类中加入注解:

需要ehcache-1.2.3.jar包:

还需要 commons_loging1.1.1.jar

实体类中通过注解可以配置实用二级缓存:

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)


(1)

usage: 给定缓存的并发策略(NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)

(2)

region (可选的):缓存范围(默认为类的全限定类名或是集合的全限定角色名)

(3)

include (可选的):值为all时包括了所有的属性(proterty), 为non-lazy时仅含非延迟属性(默认值为all)



Load默认使用二级缓存,就是当查一个对象的时候,它先会去二级缓存里面去找,如果找到了就不去数据库中查了。

Iterator默认的也会使用二级缓存,有的话就不去数据库里面查了,不发送select语句了。

List默认的往二级缓存中加数据,假如有一个query,把数据拿出来之后会放到二级缓存,但是执行查询的时候不会到二级缓存中查,会在数据库中查。原因每个query中查询条件不一样。

也可以在需要被缓存的对象中hbm文件中的<class>标签下添加一个<cache>子标签:

 <hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Order" table="orders">
            <cache usage="read-only"/>
            <id name="id" type="string">
                <column name="id"></column>
                <generator class="uuid"></generator>
            </id>
           
            <property name="orderNumber" column="orderNumber" type="string"></property>
            <property name="cost" column="cost" type="integer"></property>
           
            <many-to-one name="customer" class="com.suxiaolei.hibernate.pojos.Customer" 
                         column="customer_id" cascade="save-update">
            </many-to-one>       
        </class>
    </hibernate-mapping>
存在一对多的关系,想要在在获取一方的时候将关联的多方缓存起来,需要再集合属性下添加 <cache> 子标签,这里需要将关联的对象的  hbm 文件中必须在存在 <class> 标签下也添加 <cache> 标签,不然 Hibernate 只会缓存 OID

<hibernate-mapping>
        <class name="com.suxiaolei.hibernate.pojos.Customer" table="customer">
            <!-- 主键设置 -->
            <id name="id" type="string">
                <column name="id"></column>
                <generator class="uuid"></generator>
            </id>
           
            <!-- 属性设置 -->
            <property name="username" column="username" type="string"></property>
            <property name="balance" column="balance" type="integer"></property>
           
            <set name="orders" inverse="true" cascade="all" lazy="false" fetch="join">
                <cache usage="read-only"/>
                <key column="customer_id" ></key>
                <one-to-many class="com.suxiaolei.hibernate.pojos.Order"/>
            </set>
        </class>
    </hibernate-mapping>


默认情况下,Load()会使用二级缓存,iterator()默认使用二级缓存

list默认会往二级缓存加数据,但是查询的时候不使用


查询缓存:

(1)

<!-- 使用查询缓存 -->
<property name="cache.use_query_cache">true</property>    
(2)

调用Query的.setCachable(true)方法指明使用二级缓存 


5.缓存算法

LRU  -->  Least Recently Used  -->最近最少使用

LFU  -->  Least Frequently  Used  -->最近不常被使用(命中率高低)

FIFO --> 先进先出


设置:MemoryStoreEvictionPolicy="LRU"  (ehcache)    ===>在

<cache name="com.suxiaolei.hibernate.pojos.Order" maxElementsInMemory="200" eternal="false" 
        timeToIdleSeconds="50" timeToLiveSeconds="60" overflowToDisk="true"></cache>
中的一个参数

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值