hibernate缓存(cache)-一些心得

  什么是缓存,为什么使用缓存的这些问题我就不再阐述了。

 

  直接进入正题,hibernate分为一级缓存和二级缓存,这里主要说的是二级缓存。

 

  从配置开始 src 下创建文件名为:ehcache.xml

 

<ehcache>



    <diskStore path="java.io.tmpdir"/>





    <defaultCache

        maxElementsInMemory="10000"

        eternal="false"

        overflowToDisk="true"

        timeToIdleSeconds="7200"

        timeToLiveSeconds="3600"

        diskPersistent="false"

        diskExpiryThreadIntervalSeconds="120"

        />


        

</ehcache>
 

hibernate.cfg.xml加上

 

<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>

 

<property name="hibernate.cache.use_query_cache">true</property>

 

在hibernate查询代码里加上query.setCacheable(true);

 

这时已经开启了二级缓存,具体细节不做具体描述,因为我写这个东西的本意是想记录下如果合理使用二级缓存。

 

  当然我们知道hibernate里有两种方法获取一个列表数据分别为.iterator()和.list(),那么什么时候使用iterator什么时候使用list呢?

 

  场景一:

 

  获得数据库论坛板块信息,我们知道,数据库论坛板块的信息,基本上半年一年才变动一次,而且每次发送到数据库的sql语句,和返

 

回来的数据基本上都是一模一样的(也就是数据信息和sql语句(搜索条件)很少会修改的),那么这个时候我们应该考虑使用list方法来返回

 

信息,因为list方法第一次执行的时候会把数据库的数据信息都存放到二级缓存中,同时会记录你发送的sql语句,如果下次你还是利用

 

list方法发送一模一样的sql语句,同时数据也没有在被hibernate知道的情况下修改过,那么第二次甚至第n次再执行这个语句的时

 

候,hibernate是不用连接数据库的,而是直接把缓存里的数据返回给你。

 

  场景二:

 

  获得论坛某个板块的最新的20条信息,我们知道,论坛的第一页总是显示新发布或则有新回复的帖子,那么我们这个时候能使用list

 

方法来获取信息吗?答案是否定的。它虽然满足了list的条件之一(搜索条件很少会修改的),但是未满足另外一个条件,因为它数据信

 

息的修改是很频繁的(有新帖,或新回复的帖),那么这个时候我们就得考虑使用iterator来获取数据信息,iterator的原理是这样的,首先

 

先发送一条语句(iterator时query的sql:select * from table where id>n 真正发送:select id from table where id>n)获得所有符

 

合条件的ID,然后到二级缓存里边去找这个对象,如果发现,则获取它,如果没发现,则发送一条语句获得该ID的对象(n+1问题),比

 

方说,我们要获得最新20条信息(之前已经查询过一次,但现在有一个新帖),使用iterator方法会先发送一条语句获得满足SQL语句条

 

件的所有的ID,然后因为之前已经查询过一次,所以缓存里边已经有其中的19个帖子的缓存(因为有一个是新帖还没被hibernate查询

 

过,所以缓存里边还没有),然后再发送一条条件为ID=新帖ID的SQL语句来获得这个新帖的对象。

 

总结:

当hibernate二级缓存开启时,只要是经由hibernate的session对象来获得的任何对象hibernate都会把它放到缓存里

 

边,当该对象被修改或删除时,hibernate会把该对象在二级缓存中也删除掉。list方法一次获得所有数据同时放到缓存

 

中,如果SQL语句不变同时数据也没被改变的情况下,list直接取的缓存而不用再连接数据库进行检索操作,iterator方法用

 

n+1此来获得所有数据信息同时放到缓存中,不管SQL语句变没变始终会发送一条获得ID的SQL语句,然后根据ID查找缓

 

存,如果没有则再发送一条SQL语句获得该对象,虽然iterator始终会发送一条或(n+1)条,但发送的语句都是根据ID来获

 

取的,所以速度也是非常可观的(相对没有任何缓存机制而言)。

 

如果某个地方还没理解,或是我理解有误的地方还请指出,感谢。

 

 

阅读更多

没有更多推荐了,返回首页