Hibernate緩存級別教程

開始使用Hibernate的人們常見的問題之一就是性能,如果您沒有太多的Hibernate經驗,您會發現應用程序變慢的速度。 如果啟用sql跟蹤,您將看到有多少查詢被發送到數據庫,而這些查詢幾乎不需要Hibernate知識就可以避免。 在當前文章中,我將解釋如何使用休眠查詢緩存來避免應用程序和數據庫之間的通信量。

Hibernate提供了兩個緩存級別:

  • 一級緩存是會話緩存。 對象被緩存在當前會話中,并且它們僅在會話關閉之前是活動的。
  • 只要會話工廠處于活動狀態,第二級緩存就存在。 請記住,在Hibernate情況下,二級緩存不是對象樹。 對象實例不被緩存,而是存儲屬性值。

在簡要介紹了一下Hibernate緩存之后(讓我知道這很簡短),讓我們看一下什么是查詢緩存以及如何與二級緩存相關聯。

查詢緩存負責將作為參數提供的查詢和值的組合作為鍵進行緩存,并將查詢執行返回的對象的標識符列表作為值進行緩存。 注意,使用查詢緩存也需要二級緩存,因為從緩存(即標識符列表)獲取查詢結果時, Hibernate將使用二級緩存的標識符加載對象。

概括起來,作為一個概念性的模式,給出下一個查詢:“ from country from country>:number “,第一次執行后, Hibernate緩存將包含下一個虛構值(請注意,number參數設置為1000):

L2快取
[
id:1,{name ='Spain',人口= 1000,...。} id:2,{name ='德國',人口= 2000,...} …。 QueryCache [{來自人口>:number的國家/地區,1000},{id:2}]

因此,在開始使用查詢緩存之前,我們需要配置第二級緩存。
首先,您必須確定要使用的緩存提供程序。 對于此示例,選擇了Ehcache ,但請參閱Hibernate文檔以獲取所有支持的提供程序的完整列表。

要配置二級緩存,請設置下一個休眠屬性:

hibernate.cache.provider_class = org.hibernate.cache.EhCacheProvider
hibernate.cache.use_structured_entries = true
hibernate.cache.use_second_level_cache = true

如果您使用注釋方法,請使用以下方法注釋可緩存的實體:

@可緩存
@Cache(用法= CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)

可以看到在這種情況下,緩存并發策略是NONSTRICT_READ_WRITE ,但是根據緩存提供者的不同,可以遵循其他策略,例如TRANSACTIONAL,READ_ONLY ………請查看Hibernate文檔的緩存部分,以選擇最適合您需求的策略。

最后添加Ehcache依賴項:

<依賴性>
<groupId> net.sf.ehcache </ groupId>
<artifactId> ehcache-core </ artifactId> <version> 2.5.0 </ version> </ dependency> <依賴性> <groupId> org.hibernate </ groupId> <artifactId> hibernate-ehcache </ artifactId> <version> 3.6.0.Final </ version> </ dependency>

現在已配置了二級緩存,但未配置查詢緩存 ; 無論如何,我們離目標不遠。

hibernate.cache.use_query_cache屬性設置為true

對于每個可緩存的查詢,我們必須在查詢創建期間調用setCachable方法:

List <Country> list = session.createQuery(“來自人口> 1000的國家/地區”).setCacheable(true).list();

為了使示例更實用,我已經使用Spring Framework上傳了完整的查詢緩存示例。 為了清楚地了解查詢緩存的工作原理,我使用了一個在ensembl.org中托管的公共數據庫。 Ensembl項目為脊椎動物和其他真核生物建立了基因組數據庫,并在線免費提供此信息。 在此示例中,對dna表的查詢被緩存。

首先進行Hibernate配置:

@Configuration
public class HibernateConfiguration {@Value("#{dataSource}")private DataSource dataSource;@Beanpublic AnnotationSessionFactoryBean sessionFactoryBean() {Properties props = new Properties();props.put("hibernate.dialect", EnhancedMySQL5HibernateDialect.class.getName());props.put("hibernate.format_sql", "true");props.put("hibernate.show_sql", "true");props.put("hibernate.cache.provider_class", "org.hibernate.cache.EhCacheProvider");props.put("hibernate.cache.use_structured_entries", "true");props.put("hibernate.cache.use_query_cache", "true");props.put("hibernate.cache.use_second_level_cache", "true");props.put("hibernate.hbm2ddl.auto", "validate");AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();bean.setAnnotatedClasses(new Class[]{Dna.class});  bean.setHibernateProperties(props);bean.setDataSource(this.dataSource);bean.setSchemaUpdate(true);return bean;}}

這是一個簡單的Hibernate配置,使用前面說明的屬性來配置二級緩存。

實體類是代表DNA序列的實體。

@Entity(name="dna")
@Cacheable
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Dna {@Idprivate int seq_region_id;private String sequence;public int getSeq_region_id() {return seq_region_id;}public void setSeq_region_id(int seq_region_id) {this.seq_region_id = seq_region_id;}@Columnpublic String getSequence() {return sequence;}public void setSequence(String sequence) {this.sequence = sequence;}}

為了嘗試查詢緩存 ,我們將實現一項測試,其中多次執行同一查詢。

@Autowired
private SessionFactory sessionFactory;@Test
public void fiftyFirstDnaSequenceShouldBeReturnedAndCached() throws Exception {for (int i = 0; i < 5; i++) {Session session = sessionFactory.openSession();session.beginTransaction();Time elapsedTime = new Time("findDna"+i);List<Dna> list = session.createQuery("from dna").setFirstResult(0).setMaxResults(50).setCacheable(true).list();session.getTransaction().commit();session.close();elapsedTime.miliseconds(System.out);for (Dna dna : list) {System.out.println(dna);}}
}

我們可以看到我們正在返回前五十個dna序列,如果執行它,您將看到打印了從查詢創建到提交事務之間的經過時間。 如您所料,僅第一次迭代就需要大約5秒鐘來獲取所有數據,而其他迭代只需數毫秒。

查詢迭代之前的foreach行將通過控制臺打印對象標識符。 如果仔細觀察,這些標識符將不會在所有執行期間重復。 這個事實只是向您顯示Hibernate緩存不會保存對象而是保存屬性值,并且每次都會創建對象本身。

最后一點,請記住,默認情況下, Hibernate不緩存關聯。

現在,在編寫查詢之后,考慮它是否將包含靜態數據以及是否將經常執行。 在這種情況下, 查詢緩存是您的朋友,可以使Hibernate應用程序運行得更快。

下載代碼

參考:來自JCG合作伙伴的 Hibernate緩存級別教程 ? 在一個罐子統治他們所有博客的亞歷克斯·索托。


翻譯自: https://www.javacodegeeks.com/2012/02/hibernate-cache-levels-tutorial.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/373361.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373361.shtml
英文地址,請注明出處:http://en.pswp.cn/news/373361.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

java方法執行的時間_計算Java中任意一個方法的執行時間的工具類

1 packagealgorithm.study.utils;23 importjava.lang.reflect.Method;45 /**6 * This class is getting a method execute time and provide some other functions.7 *8 *authorygh 2017年2月24日9 */10 public classMethodExecuteTimeUtils {1112 /**13 * Get a method execut…

如何在 IIS 中設置 HTTPS 服務

Windows Server2008、IIS7啟用CA認證及證書制作完整過程 這篇文章介紹了如何安裝證書申請工具&#xff1b; 如何在iis創建證書申請&#xff1b; 如何使用iis申請證書生成的txt文件&#xff0c;在工具中開始申請證書&#xff1b; 如何導出證書&#xff1b; 以及在網站中開始使用…

Android之衛星菜單的實現

衛星菜單是現在一個非常受歡迎的“控件”&#xff0c;很多Android程序員都趨之若鶩&#xff0c;預覽如下圖。傳統的衛星菜單是用Animation實現的&#xff0c;需要大量的代碼&#xff0c;而且算法極多&#xff0c;一不小心就要通宵Debug。本帖貼出用屬性動畫Animator來實現衛星菜…

Java中的WADL:溫和的介紹

WADL&#xff08; Web應用程序描述語言 &#xff09;對REST而言&#xff0c;WSDL對SOAP而言。 這種語言的僅僅存在引起了很多爭議&#xff08;請參閱&#xff1a; 我們需要WADL嗎&#xff1f; 或者 需要 WADL還是不需要WADL &#xff09;。 我可以想到使用WADL的一些合法用例&a…

類成員函數模板特化

//類成員函數模板特化 #include <stdio.h> class A{ public:template <class T>void Print(){printf("A template\n");} };template<> void A::Print<int>(){printf("int\n"); }int main(){A a;a.Print<double>();a.Print&l…

為云量身定制您的服務

相信大家都聽說過Amazon的AWS。作為業內最為成熟的云服務提供商&#xff0c;其運行規模&#xff0c;穩定性&#xff0c;安全性都已經經過了市場的考驗。時至今日&#xff0c;越來越多的應用被部署在了AWS之上。這其中不乏Zynga及Netflix這樣著名的服務。 然而這一切并沒有停滯不…

在Vaadin和JSF之間選擇

隨著最新版本的Primefaces 3.0的發布&#xff0c;JSF終于達到了前所未有的成熟度和實用性&#xff0c;使其與其他流行的Rich Internet Applications&#xff08;RIA&#xff09;選項如Google Web Toolkit&#xff08;GWT&#xff09;&#xff0c;ExtJS&#xff0c;Vaadin&#…

20145202馬超《信息安全系統設計基礎》實驗二總結

[實驗二]&#xff08;http://www.cnblogs.com/nizaikanwoma/p/6131778.html&#xff09; 轉載于:https://www.cnblogs.com/tuolemi/p/6131987.html

java 連接ldap_ldap java 連接demo

public class LDAPHelper {/*** LDAP可以理解為一個多級目錄&#xff0c;這里&#xff0c;表示要連接到那個具體的目錄*/private final String baseDn "ouPeople,dcchangyeyi,dccom";private LdapContext ctx null;private final Control[] connCtls null;private…

flask開發restful api系列(1)

在此之前&#xff0c;向大家說明的是&#xff0c;我們整個框架用的是flask sqlalchemy redis。如果沒有開發過web&#xff0c;還是先去學習一下&#xff0c;這邊只是介紹如果從開發web轉換到開發移動端。如果flask還不是很熟悉&#xff0c;我建議先到這個網站簡單學習一下&am…

Apache Commons Lang StringUtils

因此&#xff0c;認為最好談論我喜歡的另一個Java庫。 它已經存在了一段時間&#xff0c;也許不是最令人興奮的庫&#xff0c;但是它非常有用。 我可能每天都使用它。 org.apache.commons.lang.StringUtils StringUtils是Apache Commons Lang&#xff08; http://commons.apac…

JEE7:展望新時代

計劃于2012年下半年發布的Java EE 7預計的JSR都已啟動并正在運行。 Java EE 7發行版是日期驅動的&#xff0c;它將反映該行業遷移到云中時不斷變化的需求&#xff1a;任何未準備就緒的內容將推遲到Java EE 8中使用 。 這是Java EE 7平臺中不同規范的關鍵功能的更新和摘要。 1。…

Cocos2d-JS項目之UI界面的優化

測試環境&#xff1a; iphone4、iOS6.1.2、chrome 37.2062.60&#xff0c;Cocos2d-js 3.6 之前寫了不少&#xff0c;實際項目也按這個去優化了&#xff0c;也有效果&#xff0c;但到最后才發現&#xff0c;尼瑪&#xff0c;之前都搞錯了&#xff0c;之所以有效果是歪打正著。。…

java數_java大數

java大數還是很好用的&#xff01;基本加入&#xff1a;import java.math.BigInteger;import jave.math.BigDecimal;分別是大數和大浮點數。首先讀入可以用&#xff1a;Scanner input new Scanner(System.in);BigInteger a input.nextBigInteger();這樣讀還是很方便的當然還有…

【Qt之Quick模塊】6. QML語法詳解_2類型系統

描述 在QML文檔中對象層次結構的定義中可能使用的類型可以來自各種來源。它們可能是: 由QML語言原生提供通過QML模塊通過c注冊由QML模塊作為QML文檔提供 此外&#xff0c;應用程序開發人員可以通過直接注冊c類型&#xff0c;或者通過在QML文檔中定義可重用的組件(然后可以導…

JS顯示當前時間(包含農歷時間)

時間格式&#xff1a; JavaScript代碼&#xff1a; var sWeek new Array("星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六");var dNow new Date();var CalendarData new Arra…

Maven原型創建技巧

我最近需要為姜黃SOA項目創建一些Maven原型。 對于不了解的人來說&#xff0c; Maven原型是一種基于一些預先罐裝的項目模板生成項目的方法。 對于當前的姜黃SOA原型&#xff0c;它將創建一個多模塊Maven項目&#xff0c;該項目包含Interface和Service項目以及基本的WSDL和適當…

MyBatis操作指南-與Spring集成(基于注解)

轉載于:https://www.cnblogs.com/weilu2/p/mybatis_spring_integration_basic_on_annotation.html

Windows mysql boost_Win7下Boost庫的安裝

Boost庫是C領域公認的經過千錘百煉的知名C類庫&#xff0c;涉及編程中的方方面面&#xff0c;簡單記錄一下使用時的安裝過程1.boost庫的下載boost庫官網主頁&#xff1a;www.boost.org2.安裝將下載的壓縮包解壓到指定的目錄3.建立編譯工具bjam.exe在源碼目錄下執行bootstrap.ba…

5.2與終端進行對話

Linux提供了一個特殊的設備 /dev/tty &#xff0c;該設備始終是指向當前終端或者當前的登錄會話。 FILE* output fopen("/dev/tty", "w"); //向終端寫入字符串 fprintf(output, "%s\n", "world"); FILE* input fopen("/dev/tty…