Java持久性技巧有哪些,相信很多沒有經(jīng)驗的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
一個高性能的數(shù)據(jù)訪問層需要大量關(guān)于數(shù)據(jù)庫內(nèi)部、JDBC、JPA、Hibernate的知識,下面總結(jié)了一些可用來優(yōu)化企業(yè)應(yīng)用程序的重要的技術(shù)。
1. SQL語句日志
如果您用了生成符合自己使用習(xí)慣的語句的框架,則應(yīng)始終驗證每個語句的有效性和效率。測試時使用斷言機(jī)制驗證更好,因為即使在提交代碼之前,也可以捕獲N + 1個查詢問題。
數(shù)據(jù)庫的連接開銷非常大,因此您應(yīng)該始終使用連接池機(jī)制。
由于連接數(shù)由底層數(shù)據(jù)庫集群的功能給出,所以您需要盡可能快地釋放連接。
在性能調(diào)優(yōu)中,你總是要測量、設(shè)置出正確的連接池,池的大小又是差不多的。 但像FlexyPool這樣工具可以幫助您找到合適的大小,即使您已經(jīng)將應(yīng)用程序部署到生產(chǎn)環(huán)境中。
JDBC批處理允許我們在單個數(shù)據(jù)庫往返中發(fā)送多個SQL語句。性能增益在驅(qū)動程序和數(shù)據(jù)庫端都很重要。PreparedStatements 非常適合批處理,而某些數(shù)據(jù)庫系統(tǒng)(例如 Oracle)僅支持用于預(yù)處理語句的批處理。
由于JDBC為批處理定義了獨特的API(例如PreparedStatement.addBatch和PreparedStatement.executeBatch),如果您手動生成語句,那么您應(yīng)該從一開始就知道是否應(yīng)該使用批處理。 使用Hibernate,您可以切換到使用單個配置的批處理。
Hibernate 5.2 提供了會話級別的批處理,所以在這方面更加靈活。
語句緩存是您可以輕松利用的最鮮為人知的性能優(yōu)化之一。 根據(jù)基礎(chǔ)的JDBC驅(qū)動程序,可以在客戶端(驅(qū)動程序)或數(shù)據(jù)庫端(語法樹甚至執(zhí)行計劃)上緩存PreparedStatements。
當(dāng)使用Hibernate時,IDENTITY生成器不是一個好的選擇,因為它禁用了JDBC批處理。
TABLE生成器更糟糕,因為它使用一個單獨的事務(wù)來獲取新的標(biāo)識符,這會對底層事務(wù)日志以及連接池造成壓力,因為每次我們需要一個新的標(biāo)識符時都需要單獨的連接。
SEQUENCE是正確的選擇,甚至從2012版本就開始支持SQL Server。對于SEQUENCE標(biāo)識符,Hibernate一直提供優(yōu)化器,如 pooled 或 pooled-lo,這可以減少獲取新的實體標(biāo)識符值所需的數(shù)據(jù)庫往返次數(shù)。
您應(yīng)該始終在數(shù)據(jù)庫端使用正確的列類型。 列類型越緊湊,數(shù)據(jù)庫工作集中可容納的條目越多,索引將更好地適應(yīng)于內(nèi)存。 為此,您應(yīng)該利用特定于數(shù)據(jù)庫的類型(例如PostgreSQL中的IPv4地址的inet),尤其是在實現(xiàn)新自定義類型時,Hibernate非常靈活。
Hibernate 帶有許多關(guān)系映射類型,但并不是所有的關(guān)系映射類型在效率上都是相等的。
應(yīng)該避免單向集合和 @ManyToMany 列表。如果您確實需要使用實體集合,則選雙向 @OneToMany關(guān)聯(lián)。對于 @ManyToMany 關(guān)系,使用 Set(s),因為在這種情況下它們更高效,或者簡單地映射鏈接的多對多表,并將 @ManyToMany 關(guān)系轉(zhuǎn)換為兩個雙向的 @OneToMany 關(guān)聯(lián)。
然而,與查詢不同,集合不夠靈活,因為它們不易分頁,這意味著當(dāng)子關(guān)聯(lián)的數(shù)量相當(dāng)高時,我們不能使用它們。出于這個原因,你應(yīng)該考慮一個集合是否真的有必要。 在許多情況下,實體查詢可能是更好的選擇。
就繼承而言,面向?qū)ο笳Z言和關(guān)系數(shù)據(jù)庫之間的不匹配變得更加明顯。 JPA提供了SINGLE_TABLE,JOINED和TABLE_PER_CLASS來處理繼承映射,每個策略都有其優(yōu)缺點。
SINGLE_TABLE在SQL語句方面表現(xiàn)最好,但由于我們不能使用NOT NULL約束,所以我們在數(shù)據(jù)完整性方面失敗了。
當(dāng)同時提供更復(fù)雜的語句時,JOINED采用數(shù)據(jù)完整性限制。 只要你不使用基本類型的多態(tài)查詢或@OneToMany關(guān)聯(lián),這個策略就沒有問題。 它的真正的作用在于對數(shù)據(jù)訪問層上由策略模式支持的多態(tài)@ManyToOne關(guān)聯(lián)。
應(yīng)該避免使用TABLE_PER_CLASS,因為它不會生成有效的SQL語句。
在使用 JPA 和 Hibernate 時,應(yīng)該始終關(guān)注持久性上下文的大小。 出于這個原因,您不應(yīng)該過多地使用托管實體。 通過限制托管實體的數(shù)量,我們可以獲得更好的內(nèi)存管理,并且默認(rèn)的檢查機(jī)制也將更加高效。
獲取太多的數(shù)據(jù)可能是導(dǎo)致數(shù)據(jù)訪問層性能出問題的首要原因。 一個問題是,即使是只讀的 Projections,實體查詢也是專用的。
DTO projections更適合于獲取自定義視圖,而實體只能在業(yè)務(wù)流需要修改時才能獲取。
EAGER抓取是最糟糕的,您應(yīng)該避免反模式(Anti-Pattern),例如 Open-Session in View。
關(guān)系數(shù)據(jù)庫系統(tǒng)使用許多內(nèi)存緩沖區(qū)結(jié)構(gòu)來避免磁盤訪問。 數(shù)據(jù)庫緩存經(jīng)常被忽視。 我們可以通過適當(dāng)調(diào)整數(shù)據(jù)庫引擎來顯著降低響應(yīng)時間,以便工作集駐留在內(nèi)存中,而不是一直從磁盤中獲取。
應(yīng)用程序級緩存對于許多企業(yè)應(yīng)用程序來說是不可選的。 應(yīng)用程序級緩存可以減少響應(yīng)時間,同時為數(shù)據(jù)庫關(guān)閉以進(jìn)行維護(hù)或由于某些嚴(yán)重系統(tǒng)故障提供只讀輔助存儲庫。
二級緩存對于減少讀寫事務(wù)響應(yīng)時間非常有用,特別是在主從復(fù)制體系結(jié)構(gòu)中。 根據(jù)應(yīng)用程序的要求,Hibernate允許你在READ_ONLY,NONSTRICT_READ_WRITE,READ_WRITE和TRANSACTIONAL之間進(jìn)行選擇。
在性能和數(shù)據(jù)完整性方面,事務(wù)隔離級別的選擇是非常重要的。 對于多請求Web流程,為避免丟失更新,您應(yīng)該對分離的實體或 EXTENDED 持久性上下文使用 optimistic 鎖定。
為避免optimistic locking誤報,您可以使用無版本 optimistic 并發(fā)控制或基于讀寫的屬性集來拆分實體。
僅僅因為您使用JPA或Hibernate,并不意味著您不應(yīng)該使用原生查詢。 您應(yīng)該利用窗口函數(shù),CTE(公用表表達(dá)式),CONNECT BY,PIVOT 查詢。
這些構(gòu)造允許您避免獲取太多的數(shù)據(jù),以便稍后在應(yīng)用程序?qū)舆M(jìn)行轉(zhuǎn)換。 如果可以讓數(shù)據(jù)庫進(jìn)行處理,那么只能獲取最終結(jié)果,因此可以節(jié)省大量的磁盤I / O和網(wǎng)絡(luò)開銷。 為避免主節(jié)點重載,可以使用數(shù)據(jù)庫復(fù)制和擁有多個從屬節(jié)點,這樣數(shù)據(jù)密集型的任務(wù)就會在從屬節(jié)點而不是主節(jié)點上執(zhí)行。
關(guān)系數(shù)據(jù)庫的伸縮性非常好。如果Facebook、Twitter、Pinterest或StackOverflow可以擴(kuò)展他們的數(shù)據(jù)庫系統(tǒng),那么很有可能您可以將企業(yè)應(yīng)用程序擴(kuò)展到其特定的業(yè)務(wù)需求。
數(shù)據(jù)庫復(fù)制和分片是提高吞吐量的很好的方法,您應(yīng)該完全可以利用這些經(jīng)過測試的架構(gòu)模式來擴(kuò)展您的企業(yè)應(yīng)用程序。
高性能數(shù)據(jù)訪問層必須與底層數(shù)據(jù)庫系統(tǒng)互相響應(yīng)。 了解關(guān)系數(shù)據(jù)庫和正在使用的數(shù)據(jù)訪問框架的內(nèi)部工作原理可以使企業(yè)高性能應(yīng)用程序和幾乎沒有crawls的應(yīng)用程序之間產(chǎn)生差異。
看完上述內(nèi)容,你們掌握J(rèn)ava持久性技巧有哪些的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝各位的閱讀!
網(wǎng)站標(biāo)題:Java持久性技巧有哪些-創(chuàng)新互聯(lián)
地址分享:http://www.rwnh.cn/article44/dscehe.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供微信小程序、移動網(wǎng)站建設(shè)、網(wǎng)站改版、自適應(yīng)網(wǎng)站、小程序開發(fā)、網(wǎng)頁設(shè)計公司
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容