一般系统中有三种情况会绕开hibernate执行数据库操作:
1、多个应用系统同时访问一个数据库
此种情况使用hibernate二级缓存会不可避免的造成数据不一致的问题,
此时要进行详细的设计。比如在设计上避免对同一数据表的同时的写入操作,
使用数据库各种级别的锁定机制等。
2、动态表相关
所谓“动态表”是指在系统运行时根据用户的操作系统自动建立的数据表。
比如“自定义表单”等属于用户自定义扩展开发性质的功能模块,因为此时数据表是运行时建立的,所以不能进行hibernate的映射。因此对它的操作只能是绕开hibernate的直接数据库JDBC操作。
如果此时动态表中的数据没有设计缓存,就不存在数据不一致的问题。
如果此时自行设计了缓存机制,则调用自己的缓存同步方法即可。
3、使用sql对hibernate持久化对象表进行批量删除时
此时执行批量删除后,缓存中会存在已被删除的数据。
分析:
当执行了第3条(sql批量删除)后,后续的查询只可能是以下三种方式:
a. session.find()方法:
根据前面的总结,find方法不会查询二级缓存的数据,而是直接查询数据库。
所以不存在数据有效性的问题。
b. 调用iterate方法执行条件查询时:
根据iterate查询方法的执行方式,其每次都会到数据库中查询满足条件的id值,然后再根据此id 到缓存中获取数据,当缓存中没有此id的数据才会执行数据库查询;
如果此记录已被sql直接删除,则iterate在执行id查询时不会将此id查询出来。所以,即便缓存中有此条记录也不会被客户获得,也就不存在不一致的情况。(此情况经过测试验证)
c. 用get或load方法按id执行查询:
客观上此时会查询得到已过期的数据。但是又因为系统中执行sql批量删除一般是
针对中间关联数据表,对于
中间关联表的查询一般都是采用条件查询 ,按id来查询某一条关联关系的几率很低,所以此问题也不存在!
如果某个值对象确实需要按id查询一条关联关系,同时又因为数据量大使用 了sql执行批量删除。当满足此两个条件时,为了保证按id 的查询得到正确的结果,可以使用手动清楚二级缓存中此对象的数据的方法!!
(此种情况出现的可能性较小)
建议
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查询中间表对象的方法,也可以通过调用清除缓存的方法来解决。
具体的配置方法
根据我了解的很多hibernate的使用者在调用其相应方法时都迷信的相信“hibernate会自行为我们处理性能的问题”,或者“hibernate会自动为我们的所有操作调用缓存”,实际的情况是hibernate虽然为我们提供了很好的缓存机制和扩展缓存框架的支持,但是必须经过正确的调用其才有可能发挥作用!!所以造成很多使用hibernate的系统的性能问题,实际上并不是hibernate不行或者不好,而是因为使用者没有正确的了解其使用方法造成的。相反,如果配置得当hibernate的性能表现会让你有相当“惊喜的”发现。下面我讲解具体的配置方法.
ibernate提供了二级缓存的接口:
net.sf.hibernate.cache.Provider,
同时提供了一个默认的 实现net.sf.hibernate.cache.HashtableCacheProvider,
也可以配置 其他的实现 比如ehcache,jbosscache等。
具体的配置位置位于hibernate.cfg.xml文件中
<property name="hibernate.cache.use_query_cache">true</property>
<property name="hibernate.cache.provider_class">net.sf.hibernate.cache.HashtableCacheProvider</property>
很多的hibernate使用者在 配置到 这一步 就以为 完事了,
注意:其实光这样配,根本 就没有使用hibernate的二级缓存。同时因为他们在使用hibernate时大多时候是马上关闭session,所以,一级缓存也没有起到任何作用。结果就是没有使用任何缓存,所有的hibernate操作都是直接操作的数据库!!性能可以想见。
正确的办法是除了以上的配置外还应该配置每一个vo对象的具体缓存策略,在影射文件中配置。例如:
<hibernate-mapping>
<class name="com.sobey.sbm.model.entitySystem.vo.DataTypeVO" table="dcm_datatype">
<cache usage="read-write"/>
<id name="id" column="TYPEID" type="java.lang.Long">
<generator class="sequence"/>
</id>
<property name="name" column="NAME" type="java.lang.String"/>
<property name="dbType" column="DBTYPE" type="java.lang.String"/>
</class>
</hibernate-mapping>
关键就是这个<cache usage="read-write"/>,其有几个选择
read-only,read-write,transactional,等
然后在执行查询时 注意了 ,如果是条件查询,或者返回所有结果的查询,此时session.find()方法 不会获取缓存中的数据。只有调用query.iterate()方法时才会调缓存的数据。
同时 get 和 load方法 是都会查询缓存中的数据 .
分享到:
相关推荐
**标题解析:** "Hibernate教程25_Hibernate缓存" 这个标题表明了我们要讨论的是关于Hibernate框架的第25个教程,重点是它的缓存机制。Hibernate是一个流行的Java对象关系映射(ORM)框架,它允许开发者用面向对象的...
【描述】:虽然描述信息为空,但通常来说,Hibernate缓存的讨论可能涵盖如何配置和使用这些缓存,以及它们在实际项目中的作用。Hibernate的缓存机制对于处理大量读取操作和频繁查询的数据尤其有效,通过将最近或最常...
《使用Hibernate缓存数据》 在Java开发中,Hibernate是一个广泛应用的对象关系映射(ORM)框架,它极大地简化了数据库操作。为了提高性能,Hibernate引入了缓存机制,有效地减少了与数据库的交互次数,从而提升了...
【标题】:“Hibernate缓存” 在Java开发领域,Hibernate是一个非常流行的对象关系映射(ORM)框架,它简化了数据库操作并提供了强大的数据持久化能力。缓存是提高应用程序性能的关键技术之一,Hibernate中也不例外...
在Java的持久化框架Hibernate中,缓存机制和Session对象的管理是其高效运作的关键要素。本文将深入探讨这两个主题,以帮助开发者更好地理解和利用Hibernate。 首先,让我们聚焦于Hibernate的缓存机制。缓存的存在是...
本文将深入探讨 Hibernate 的缓存机制,包括其两个级别——一级缓存和二级缓存,并讨论它们的工作原理、范围、并发访问策略以及如何管理和配置。 1. **一级缓存** - **范围与作用**:一级缓存是 Session 级别的...
《Hibernate二级缓存配置详解》 在Java的持久化框架Hibernate中,缓存技术是提升系统性能的关键之一。本文将深入探讨Hibernate的二级缓存,包括其事务范围、进程范围和集群范围的配置,特别是关注进程范围内的...
接着,我们来讨论二级缓存。二级缓存是可选的,它可以跨多个Session共享数据,进一步提升性能。二级缓存通常由第三方插件如EhCache、Infinispan等提供支持。与一级缓存相比,二级缓存的生命周期更长,但它的数据一致...
2. 查询缓存:这部分尤为重要,我们今天主要讨论的就是这个主题。查询缓存存储的是查询结果集的标识,而不是完整的对象。当我们执行一个HQL(Hibernate查询语言)或SQL查询时,结果会被哈希化并存储到缓存中。如果...
本文将详细讨论如何在Java 10环境中使用Hazelcast来迁移Hibernate的二级缓存,以确保项目的顺利运行。 首先,让我们了解一下问题的背景。在Java 10中,Oracle引入了模块化系统(Project Jigsaw),这导致了一些传统...
本资源“hibernate二级缓存实例中需要的jar包.rar”包含了实现Hibernate二级缓存功能所需的库文件,下面我们将详细讨论相关的知识点。 首先,Hibernate的二级缓存分为两种主要类型:查询缓存和集合缓存。查询缓存...
【标题】与【描述】提及的是“Hibernate面试题专栏”,主要涵盖了全面的Hibernate面试题、笔试题以及相关问题,这表明我们将要讨论的是Java领域中著名的对象关系映射框架——Hibernate的相关知识。Hibernate是一个...
同时,还会讨论事务管理和并发控制,确保数据的一致性和完整性。 查询语言在Hibernate中主要有两种:HQL(Hibernate Query Language)和 Criteria API。HQL是面向对象的查询语言,类似于SQL,但更接近于Java的语法...
Ehcache最初是为Hibernate设计的数据缓存解决方案,但后来发展成为一个独立的缓存系统。Ehcache支持内存和磁盘缓存,提供对象过期策略,并且可以很容易地集成到各种Java应用中。 Java Caching System (JCS)是Apache...
4. **缓存机制**:为了提高性能,Hibernate支持多种缓存策略,书中详细介绍了如何合理地使用这些缓存选项。 5. **查询语言**:Hibernate提供了强大的查询语言HQL(Hibernate Query Language),用于执行复杂的数据库...
6. **Cascading与Invalidation**:讨论实体之间的级联操作(如级联保存、级联删除)和缓存的无效化策略。 7. **Transaction管理**:深入理解Hibernate的事务处理,包括JTA和JDBC事务模式,以及在分布式系统中的事务...
同时,作者可能还会讨论Hibernate与其他技术的集成,如Spring框架的整合,以及如何在分布式环境下使用Hibernate。 最后,书中可能包含了一些实际案例和项目实战,帮助读者将理论知识应用到实践中,提升解决实际问题...
其次,我们来讨论Hibernate的get()与load()方法。两者都是用于根据ID获取对象,但行为有所不同。get()方法假设数据库中存在对应ID的对象,若找不到则返回null。而load()方法则返回一个对象的代理,延迟加载直到真正...
本文将讨论使用 Hibernate 批量更新大量数据的方法和技巧。 批量更新的必要性 在实际应用中,我们经常需要将大量数据插入到数据库中,例如数据迁移、数据同步、数据备份等场景。在这些场景中,如果使用传统的 ...
7. **事务和并发**:讨论了Hibernate如何处理事务,以及在并发环境下如何确保数据的一致性。 8. **高级特性**:包括动态模型、延迟加载、代理、事件监听器、JPA支持等进阶话题。 9. **工具**:介绍了Hibernate提供...