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