以下配置基于spring boot版本1.4.2.RELEASE,默認引入的hibernate版本為5.0.11.Final,ehcache版本2.10.3。
Ehcache作為Hibernate的二級緩存的實現(xiàn)。
1.application.properties中,添加:
#打開hibernate統(tǒng)計信息
spring.jpa.properties.hibernate.generate_statistics = true
#打開二級緩存
spring.jpa.properties.hibernate.cache.use_second_level_cache = true
#打開查詢緩存
spring.jpa.properties.hibernate.cache.use_query_cache = true
#指定緩存provider
spring.jpa.properties.hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
#配置shared-cache-mode
spring.jpa.properties.javax.persistence.sharedCache.mode = ENABLE_SELECTIVE
2.接口從JpaSpecificationExecutor繼承
根據(jù)具體Entity類型,重寫JpaSpecificationExecutor中的方法,并且加上@QueryHints注解
// 不涉及分頁的查詢
@QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value ="true") }) // 使用查詢緩存
List<UserAddress> findAll(Specification<UserAddress> spec, Sort sort);
// 分頁查詢
@QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value ="true") }) // 使用查詢緩存
Page<UserAddress> findAll(Specification<UserAddress> spec, Pageable pageable);
3.總結(jié)
通過上述配置,在不涉及到分頁查詢的情況下,確實實現(xiàn)了查詢緩存。
通過緩存事件監(jiān)聽,查詢結(jié)果確實放入了查詢緩存中。
在第二次查詢的情況下,不會發(fā)出查詢sql。
而對于分頁查詢來說,每次分頁查詢會發(fā)出兩條查詢sql。
第一條為:select count(xxx.id) from ..........;
第二條為:select xxx, xxx,....from ....;
通過緩存事件監(jiān)聽,select count的查詢結(jié)果并未被放入查詢緩存;而select的查詢結(jié)果確實被放入了查詢緩存中。
所以在第二次分頁查詢的情況下,仍然會發(fā)出一條select count語句;而select的sql確實沒有發(fā)出。
4.疑問
雖說對于不涉及分頁的查詢,能夠?qū)崿F(xiàn)查詢緩存;對于涉及分頁的查詢,部分實現(xiàn)了查詢緩存。
但總覺得這種方式不夠優(yōu)雅,不知道同學們有沒有更好的解決方案。