关于hibernate的缓存使用(二)

2014-11-24 01:40:16 · 作者: · 浏览: 1
经过测试验证)

c. 用get或load方法按id执行查询:

客观上此时会查询得到已过期的数据。但是又因为系统中执行sql批量删除一般是

针对中间关联数据表,对于

中间关联表的查询一般都是采用条件查询,按id来查询某一条关联关系的几率很低,所以此问题也不存在!

如果某个值对象确实需要按id查询一条关联关系,同时又因为数据量大使用 了sql执行批量删除。当满足此两个条件时,为了保证按id 的查询得到正确的结果,可以使用手动清楚二级缓存中此对象的数据的方法!!

(此种情况出现的可能性较小)

1.5. 建议

1、建议不要使用sql直接执行数据持久化对象的数据的更新,但是可以执行 批量删除。(系统中需要批量更新的地方也较少)

2、如果必须使用sql执行数据的更新,必须清空此对象的缓存数据。调用

SessionFactory.evict(class)

SessionFactory.evict(class,id)

等方法。

3、在批量删除数据量不大的时候可以直接采用hibernate的批量删除,这样就不存在绕开hibernate执行sql产生的缓存数据一致性的问题。

4、不推荐采用hibernate的批量删除方法来删除大批量的记录数据。

原因是hibernate的批量删除会执行1条查询语句外加 满足条件的n条删除语句。而不是一次执行一条条件删除语句!!

当待删除的数据很多时会有很大的性能瓶颈!!!如果批量删除数据量较大,比如超过50条,可以采用JDBC直接删除。这样作的好处是只执行一条sql删除语句,性能会有很大的改善。同时,缓存数据同步的问题,可以采用hibernate清除二级缓存中的相关数据的方法。

调用SessionFactory.evict(class) ;SessionFactory.evict(class,id)等方法。

所以说,对于一般的应用系统开发而言(不涉及到集群,分布式数据同步问题等),因为只在中间关联表执行批量删除时调用了sql执行,同时中间关联表一般是执行条件查询不太可能执行按id查询。所以,此时可以直接执行sql删除,甚至不需要调用缓存的清除方法。这样做不会导致以后配置了二级缓存引起数据有效性的问题。

退一步说,即使以后真的调用了按id查询中间表对象的方法,也可以通过调用清除缓存的方法来解决。

4、具体的配置方法

根据我了解的很多hibernate的使用者在调用其相应方法时都迷信的相信“hibernate会自行为我们处理性能的问题”,或者“hibernate会自动为我们的所有操作调用缓存”,实际的情况是hibernate虽然为我们提供了很好的缓存机制和扩展缓存框架的支持,但是必须经过正确的调用其才有可能发挥作用!!所以造成很多使用hibernate的系统的性能问题,实际上并不是hibernate不行或者不好,而是因为使用者没有正确的了解其使用方法造成的。相反,如果配置得当hibernate的性能表现会让你有相当“惊喜的”发现。下面我讲解具体的配置方法.

ibernate提供了二级缓存的接口:

net.sf.hibernate.cache.Provider,

同时提供了一个默认的 实现net.sf.hibernate.cache.HashtableCacheProvider,

也可以配置 其他的实现 比如ehcache,jbosscache等。

具体的配置位置位于hibernate.cfg.xml文件中

true

net.sf.hibernate.cache.HashtableCacheProvider

很多的hibernate使用者在 配置到 这一步 就以为 完事了,

注意:其实光这样配,根本 就没有使用hibernate的二级缓存。同时因为他们在使用hibernate时大多时候是马上关闭session,所以,一级缓存也没有起到任何作用。结果就是没有使用任何缓存,所有的hibernate操作都是直接操作的数据库!!性能可以想见。

正确的办法是除了以上的配置外还应该配置每一个vo对象的具体缓存策略,在影射文件中配置。例如:

关键就是这个,其有几个选择

read-only,read-write,transactional,等

然后在执行查询时 注意了 ,如果是条件查询,或者返回所有结果的查询,此时session.find()方法 不会获取缓存中的数据。只有调用query.iterate()方法时才会调缓存的数据。

同时get 和load方法 是都会查询缓存中的数据.

对于不同的缓存框架具体的配置方法会有不同,但是大体是以上的配置

(另外,对于支持事务型,以及支持集群的环境的配置我会争取在后续的文章中中 发表出来)

3. 总结

总之是根据不同的业务情况和项目情况对hibernate进行有效的配置和正确的使用,扬长避短。不存在适合于任何情况的一个“万能”的方案。

以上结论及建议均建立在自己在对Hibernate 2.1.2中的测试结果以及以前的项目经验的基础上。如有谬处,请打家提出指正:)!