Spring Boot集成Hibernate二级缓存配置问题咨询
Spring Boot中Hibernate二级缓存配置后的常见问题解答
看起来你已经完成了Hibernate二级缓存的基础配置,我先帮你梳理下已做的配置,再针对这类场景下的常见问题给出实用解答:
已完成的配置梳理
1. Maven依赖配置
你在pom.xml中添加了ehcache的依赖:
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-ehcache</artifactId> <version>5.2.2.Final</version> </dependency>
2. 缓存核心配置
在application.properties中开启了二级缓存并指定了缓存区域工厂:
spring.jpa.properties.hibernate.cache.use_second_level_cache=true spring.jpa.properties.hibernate.cache.region.factory_class=org.hibernate.cache.ehcache.EhCacheRegionFactory
3. 统计功能开启
你提到开启了Hibernate统计功能,完整的配置项应该是:
spring.jpa.properties.hibernate.generate_statistics=true
这个配置能帮你后续直观验证缓存是否生效。
常见问题及解决方案
Q1: 如何让实体类被二级缓存管理?
仅仅开启全局缓存还不够,你需要给目标实体类添加Hibernate缓存注解,指定缓存策略:
import javax.persistence.Entity; import javax.persistence.Id; import org.hibernate.annotations.Cache; import org.hibernate.annotations.CacheConcurrencyStrategy; @Entity @Cache(usage = CacheConcurrencyStrategy.READ_WRITE, region = "UserCache") public class User { @Id private Long id; private String username; // getter、setter省略 }
CacheConcurrencyStrategy的常用值:
READ_ONLY:适合只读数据,性能最优READ_WRITE:适合频繁读写的场景NONSTRICT_READ_WRITE:适合对一致性要求不高的读写场景TRANSACTIONAL:适合需要事务支持的场景
Q2: 怎么验证二级缓存真的生效了?
利用你开启的统计功能,有两种简单验证方式:
- 查看日志输出
添加日志配置,让Hibernate打印缓存统计信息:
logging.level.org.hibernate.stat=DEBUG
执行两次相同的查询操作,日志中会出现类似cache hits: 1, cache misses: 0的记录,说明第二次查询命中了缓存。
- 代码中获取统计数据
通过SessionFactory直接获取缓存统计对象:
import org.hibernate.Session; import org.hibernate.stat.Statistics; import org.springframework.stereotype.Component; @Component public class CacheStatsChecker { public void printCacheStats(Session session) { Statistics stats = session.getSessionFactory().getStatistics(); System.out.println("二级缓存命中次数: " + stats.getSecondLevelCacheHitCount()); System.out.println("二级缓存未命中次数: " + stats.getSecondLevelCacheMissCount()); } }
Q3: 如何自定义缓存的过期、容量规则?
你需要在src/main/resources下添加ehcache.xml配置文件,为指定缓存区域设置精细规则:
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd"> <!-- 默认缓存规则 --> <defaultCache maxEntriesLocalHeap="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false"/> <!-- 对应实体类中指定的UserCache区域 --> <cache name="UserCache" maxEntriesLocalHeap="500" eternal="false" timeToIdleSeconds="300" timeToLiveSeconds="600"/> </ehcache>
关键参数说明:
maxEntriesLocalHeap:堆内存中允许的最大缓存条目数eternal:是否永久缓存(设为true则忽略过期时间)timeToIdleSeconds:缓存对象空闲多久后自动过期timeToLiveSeconds:缓存对象创建后多久自动过期
Q4: 二级缓存和查询缓存有什么区别?
你当前配置的是二级缓存(针对单个实体对象的缓存),如果需要缓存JPQL/HQL的查询结果,还需要开启查询缓存:
spring.jpa.properties.hibernate.cache.use_query_cache=true
然后在查询方法上添加@QueryHint标记:
import org.springframework.data.jpa.repository.Query; import org.springframework.data.jpa.repository.QueryHints; import org.springframework.data.repository.CrudRepository; import javax.persistence.QueryHint; import java.util.List; public interface UserRepository extends CrudRepository<User, Long> { @QueryHints(value = { @QueryHint(name = "org.hibernate.cacheable", value = "true") }) @Query("SELECT u FROM User u WHERE u.username LIKE %?1%") List<User> findByUsernameContaining(String keyword); }
内容的提问来源于stack exchange,提问作者Fabio Ebner
相关产品推荐
相关产品推荐

