JPA –我应该成为懒惰的极端主义者吗?
當(dāng)您與開發(fā)人員討論將對(duì)象映射到關(guān)系數(shù)據(jù)庫時(shí),他們經(jīng)常抱怨JPA性能差,JPA提供程序的行為不可預(yù)測(cè)等。通常,在對(duì)話的某些時(shí)候,您會(huì)聽到: “讓我們完全放棄這項(xiàng)技術(shù),我們?cè)谏蟼€(gè)月的會(huì)議上看到了更好的東西。 我們將在我們的項(xiàng)目中使用它而不是JPA,并從此以后快樂地開發(fā)它們。” - 聽起來很熟悉? 學(xué)習(xí)新技術(shù)沒錯(cuò),事實(shí)上,您應(yīng)該不斷地做下去,以提高您的技能和知識(shí),但是當(dāng)您遇到其中一種問題時(shí),您會(huì)選擇一條通向另一種技術(shù)的簡(jiǎn)單途徑還是會(huì)問自己: “我是嗎? 以正確的方式使用它?” 讓我們看一下JPA用法示例。 假設(shè)我們有簡(jiǎn)單的數(shù)據(jù)庫,映射到實(shí)體:
而且我們必須顯示所有員工姓名,無論其雇主(和部門)如何。 沒有比這容易的事了-簡(jiǎn)單的JPQL查詢就能做到:
select employee from Employee employee order by employee.name許多開發(fā)人員在這一點(diǎn)上完成工作,并與Friends一起慶祝他們生活中另一個(gè)成功的JPQL查詢,但是我們當(dāng)中有些人感到這種奇怪的感覺,即有些令人毛骨悚然的東西潛伏在光亮的表面之下。 JPA提供程序(例如Hibernate)產(chǎn)生的SQL查詢將揭示事實(shí):
select [...] from EMPLOYEE employee0_ order by employee0_.EMPLOYEE_NAMENothing special, so far , but here comes the naked truth:select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=?select [...] from EMPLOYER employer0_ where employer0_.EMPLOYER_ID=?select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=?select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=?select [...] from DEPARTMENT department0_ left outer join EMPLOYER employer1_ on department0_.EMPLOYER_ID=employer1_.EMPLOYER_ID where department0_.DEPARTMENT_ID=?有沒有搞錯(cuò)?! 這些查詢是什么? –好吧,原因在于@ManyToOne批注的默認(rèn)訪 存屬性值,即EAGER 。 我的數(shù)據(jù)庫包含2個(gè)雇主,其中一個(gè)擁有4個(gè)部門,而第二個(gè)則沒有。 加載Employee時(shí),默認(rèn)情況下,JPA提供程序會(huì)加載所有EAGER關(guān)聯(lián)(在我們的示例中是Department和Employer),因此我們還有其他查詢。 如上所示,JPA提供者足夠聰明,可以在可能的情況下立即加載雇主和部門。
您剛剛發(fā)現(xiàn)了神奇的JPQL查詢,可一次獲取所有數(shù)據(jù)庫內(nèi)容 。 這種情況會(huì)讓您想起過去的事情嗎? 我們對(duì)于它可以做些什么呢? –我的朋友,您所需要的只是懶惰–除非真正需要,否則不要使用EAGER (請(qǐng)記住, @ ManyToOne和@OneToOne注釋默認(rèn)使用它)。
此時(shí)您可能稱我為瘋子或懶惰極端主義者,并問:您是否遇到過LazyInitializationException ,兄弟! 您是否聽說過延遲加載問題的所有麻煩!? 性能下降等。。。我當(dāng)然這樣做了,但是您不認(rèn)為如果我們?cè)贘PA方面遇到麻煩,也許我們會(huì)以錯(cuò)誤的方式使用它! 我們通常在Web應(yīng)用程序中所做的是在UI上呈現(xiàn)或編輯一些數(shù)據(jù),并且通常只是特定實(shí)體屬性的一小部分。 要做到這一點(diǎn),需要從數(shù)據(jù)庫中獲取實(shí)體樹–我們不知不覺中就問實(shí)體管理器:給我所有員工,按名稱排序,以及所有相關(guān)實(shí)體,然后抱怨性能下降! 我們不在乎從數(shù)據(jù)庫中獲取什么,因?yàn)閷?shí)體管理器將為我們完成驢工作。 我們得到LazyInitializationException ,那么! 我們將以“視圖”模式使用“打開實(shí)體管理器”,并消除此愚蠢的異常!
休息一下! 你不認(rèn)為這是一個(gè)死胡同嗎? –現(xiàn)在該改變一些東西了。 您可以在項(xiàng)目中使用復(fù)雜的方法,例如CQRS ,以及JPA中已經(jīng)存在的可能性,這些方法可以幫助您更改本文中我描述的不良方式。
甜點(diǎn)的幾個(gè)鏈接:
- CQRS信息
- 馬丁·福勒(Martin Fowler)關(guān)于CQRS的文章
翻譯自: https://www.javacodegeeks.com/2013/05/jpa-should-i-become-a-laziness-extremist.html
總結(jié)
以上是生活随笔為你收集整理的JPA –我应该成为懒惰的极端主义者吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 美国有证监会吗?
- 下一篇: 美联储降息25基点是多少?