hibernate jpa_JPAHibernate替代方案。 如果JPA或Hibernate对于我的项目而言不够好,该怎么办?...
hibernate jpa
你好!你好嗎? 今天我們將討論不建議使用JPA / Hibernate的情況。 在JPA領(lǐng)域之外,我們還有哪些選擇?
我們將談?wù)摰氖?#xff1a;
- JPA /Hibernate問題
- 解決一些JPA /Hibernate問題的方法
- 選擇此處描述的框架的標準
- Spring JDBC模板
- MyBatis
- 索莫拉
- sql2o
- 看看:jOOQ和Avaje
- 原始的JDBC方法值得嗎?
- 如何選擇正確的框架?
- 最后的想法
我使用本文中提到的框架在github中創(chuàng)建了4個CRUD,您將在每個頁面的開頭找到URL。
我并不是認為JPA一文不值的激進主義者,但我確實相信我們需要針對每種情況選擇正確的框架。 如果您不知道我寫了一本JPA書(僅葡萄牙語),并且我認為JPA是解決所有問題的靈丹妙藥。
JPA /Hibernate問題
有時候,JPA弊大于利。 在下面,您將看到JPA /Hibernate問題,在下一頁中,您將看到一些針對這些問題的解決方案:
- 復(fù)合密鑰:我認為,這是JPA開發(fā)人員最大的麻煩。 當(dāng)我們映射一個組合鍵時,當(dāng)我們需要持久化或在數(shù)據(jù)庫中找到一個對象時,這給項目增加了巨大的復(fù)雜性。 當(dāng)您使用組合鍵時,可能會發(fā)生一些問題,其中一些問題可能是實現(xiàn)錯誤。
- 舊版數(shù)據(jù)庫:當(dāng)需要調(diào)用StoredProcedures或Functions時,數(shù)據(jù)庫中包含許多業(yè)務(wù)規(guī)則的項目可能會成為問題。
- 工件大小:如果您使用的是Hibernate實現(xiàn),那么工件大小會增加很多。 Hibernate使用了大量依賴項,這些依賴項會增加生成的jar / war / ear的大小。 如果開發(fā)人員需要在Internet帶寬較低(或上傳速度較慢)的多個遠程服務(wù)器中進行部署,則工件大小可能會成為問題。 想象一個項目,在每個新版本中,有必要在全國范圍內(nèi)更新10個客戶服務(wù)器。 上載速度慢,文件損壞和Internet丟失等問題可能會導(dǎo)致開發(fā)人員/運營團隊浪費更多時間。
- 生成SQL:JPA的優(yōu)勢之一是數(shù)據(jù)庫的可移植性,但是要使用此可移植性的優(yōu)勢,您需要使用JPQL / HQL 語言 。 當(dāng)生成的查詢性能較差并且不使用為優(yōu)化查詢而創(chuàng)建的表索引時,此優(yōu)點可能成為不利條件。
- 復(fù)雜查詢:這些項目使用數(shù)據(jù)庫資源(例如SUM,MAX,MIN,COUNT,HAVING等)進行多個具有高度復(fù)雜性的查詢。如果將這些資源結(jié)合使用,JPA性能可能會下降并且不使用表索引,否則您將無法使用可以解決此問題的特定數(shù)據(jù)庫資源。
- 框架復(fù)雜性:使用JPA創(chuàng)建CRUD非常簡單,但是當(dāng)我們開始使用實體關(guān)系,繼承,緩存,PersistenceUnit操作,具有多個實體的PersistenceContext等時,就會出現(xiàn)問題。沒有開發(fā)人員的開發(fā)團隊具有良好的JPA經(jīng)驗使用JPA“ 規(guī)則 ”將浪費很多時間。
- 處理緩慢且占用大量RAM內(nèi)存:在某些情況下,JPA會在報表處理中失去性能,插入很多實體或長時間打開的事務(wù)存在問題。
閱讀完以上所有問題后,您可能會想:“ JPA在做任何事情方面都擅長嗎?”。 JPA具有很多優(yōu)點,在此不再贅述,因為這不是后期主題,JPA是一種在很多情況下都適用的工具。 JPA的一些優(yōu)點是:數(shù)據(jù)庫可移植性,節(jié)省大量開發(fā)時間,使創(chuàng)建查詢更容易,緩存優(yōu)化,龐大的社區(qū)支持等。
在下一頁中,我們將為上述問題提供一些解決方案,這些解決方案可以幫助您避免龐大的持久性框架重構(gòu)。 我們將看到一些技巧來解決或解決此處描述的問題。
解決一些JPA /Hibernate問題的方法
如果要考慮刪除項目的JPA,則需要小心。
我不是那種認為應(yīng)該在找到解決方案之前刪除整個框架的開發(fā)人員。 有時候,最好選擇一種不那么介入的方法。
復(fù)合鍵
不幸的是,沒有很好的解決方案。 如果可能,請避免使用業(yè)務(wù)規(guī)則不需要的帶有復(fù)合鍵的表。 我已經(jīng)看到開發(fā)人員在可以應(yīng)用簡單鍵的情況下使用復(fù)合鍵,而不必要地將復(fù)合鍵復(fù)雜性添加到了項目中。
舊版數(shù)據(jù)庫
最新的JPA版本(2.1)支持StoredProcedures和Functions,有了此新資源,將更易于與數(shù)據(jù)庫進行通信。 如果無法升級JPA版本,我認為JPA不是您的最佳解決方案。
您可以使用某些供應(yīng)商資源,例如Hibernate,但是您將失去數(shù)據(jù)庫和實現(xiàn)的可移植性。
神器尺寸
解決此問題的一個簡單方法是更改??JPA實現(xiàn)。 除了使用Hibernate實現(xiàn)之外,還可以使用Eclipsellink,OpenJPA或Batoo。 如果項目使用的是Hibernate批注/資源,則可能會出現(xiàn)問題。 實現(xiàn)更改將需要一些代碼重構(gòu)。
生成SQL和復(fù)雜查詢
解決這些問題的方法是使用名為NativeQuery的資源。 使用此資源,您可以擁有簡化的查詢或優(yōu)化SQL,但是您將犧牲數(shù)據(jù)庫的可移植性。
您可以將查詢放在一個文件中,例如SEARCH_STUDENTS_ORACLE或SEARCH_STUDENTS_MYSQL,在生產(chǎn)環(huán)境中,可以訪問正確的文件。 這種方法的問題在于,必須為每個數(shù)據(jù)庫編寫相同的查詢。 如果需要編輯SEARCH_STUDENTS查詢,則需要編輯oracle和mysql文件。
如果您的項目只有一個數(shù)據(jù)庫供應(yīng)商,則NativeQuery資源不會有問題。
這種混合方法(同一項目中的JPQL和NativeQuery)的優(yōu)點是可以利用其他JPA優(yōu)點。
處理速度慢,內(nèi)存容量大
可以通過優(yōu)化查詢(使用NativeQuery),查詢分頁和小事務(wù)來解決此問題。
避免將EJB與PersistenceContext Extended一起使用,這種上下文將消耗更多的內(nèi)存和服務(wù)器處理能力。
也有可能從數(shù)據(jù)庫中獲取一個實體作為“ 只讀 ”實體,例如:將僅在報表中使用的實體。 要恢復(fù)處于打開狀態(tài)的“ 只讀 ”狀態(tài)的實體,請看下面的代碼:
String query = "select uai from Student uai"; EntityManager entityManager = entityManagerFactory.createEntityManager(); TypedQuery<Student> typedQuery = entityManager.createQuery(query, Student.class); List<Student> resultList = typedQuery.getResultList();請注意,在上面的代碼中沒有打開的事務(wù),所有返回的實體都將被分離(不受JPA監(jiān)視)。 如果使用的是EJB,則將事務(wù)標記為NOT_SUPPORTED,或者可以使用@Transactional(readOnly = true)。
復(fù)雜
我想說,解決這個問題只有一種解決方案:學(xué)習(xí)。 有必要閱讀書籍,博客,雜志或JPA材料的任何其他可靠來源。 在JPA中,更多的研究等于更少的疑問。
我不是一個開發(fā)人員,它相信JPA是解決每個問題的唯一且最佳的解決方案,但是有時候JPA并不是使用工具的最佳方法。
在決定更改持久性框架時,您必須小心,通常會影響許多類,并且需要大量的重構(gòu)。 此重構(gòu)可能會導(dǎo)致一些錯誤。 需要與項目經(jīng)理討論這種重構(gòu)并列出所有正面和負面影響。
在接下來的四頁中,我們將看到可以在我們的項目中使用的4個持久性框架,但是在看到這些框架之前,我將展示如何選擇每個框架。
選擇此處描述的框架的標準
也許您會想到:“為什么X不在這里?”。 下面,我將列出用于選擇此處顯示的框架的標準:
- 可以在多個研究來源中找到:我們可以在論壇中找到談?wù)摽蚣艿娜?#xff0c;但是要在多個論壇中找到相同的框架卻很難。 選擇了引用最多的框架。
- 由不同來源引用 :在論壇中找到的某些框架僅由其提交者指示。 一些論壇不允許使用“自我商品”,但某些框架所有者仍在這樣做。
- 最近更新時間 : 2013年1月5日 :我搜索了過去一年中已更新的框架。
- 快速的Hello World :某些框架在15分鐘至20分鐘的時間內(nèi)無法完成Hello World,并且存在一些錯誤。 對于這篇文章中的教程,我在每個框架上工作了7分鐘:從下載開始算起,直到第一個數(shù)據(jù)庫插入。
這里將顯示的框架具有良好的方法并且易于使用。 為了制作一個真實的CRUD場景,我們有一個如下的持久性模型:
- 名稱與列名稱不同的屬性:socialSecurityNumber-> social_security_number
- 日期屬性
- 一個ENUM屬性
在課堂上有了這個特性,我們將看到一些問題以及框架如何解決它。
Spring JDBC模板
我們可以找到用于訪問數(shù)據(jù)庫數(shù)據(jù)的最著名的框架之一是Spring JDBC模板。 該項目的代碼可以在這里找到: https : //github.com/uaihebert/SpringJdbcTemplateCrud
Sprint JDBC模板使用如下的本機查詢:
如上圖所示,查詢具有數(shù)據(jù)庫語法(我將使用MySQL)。 當(dāng)我們使用本機SQL查詢時,可以輕松地使用所有數(shù)據(jù)庫資源。
我們需要一個對象JDBC模板的實例(用于執(zhí)行查詢),并且要創(chuàng)建JDBC模板對象,我們需要設(shè)置一個數(shù)據(jù)源:
我們現(xiàn)在可以獲取數(shù)據(jù)源(感謝Spring注入)并創(chuàng)建我們的JDBCTemplate:
PS .:上面的所有XML代碼和JDBCTemplate實例化都可以被Spring注入和代碼引導(dǎo)替換,只需對Spring功能進行一些研究即可。 我不喜歡的一件事是ID恢復(fù)的INSERT語句,它很冗長:
使用KeyHolder類,我們可以在數(shù)據(jù)庫中恢復(fù)生成的ID,不幸的是,我們需要大量的代碼才能完成該操作。 其他CRUD功能更易于使用,如下所示:
注意,由于使用RowMapper,執(zhí)行SQL查詢非常簡單,并且會生成一個填充的對象。 RowMapper是JDBC模板用來簡化使用數(shù)據(jù)庫中數(shù)據(jù)填充類的引擎 。
看看下面的RowMapper代碼:
關(guān)于RowMapper的最好的消息是它可以在項目的任何查詢中使用。 負責(zé)編寫將填充類數(shù)據(jù)的邏輯的開發(fā)人員。 要完成此頁面,請在下面的數(shù)據(jù)庫DELETE和數(shù)據(jù)庫UPDATE語句中查看:
關(guān)于Spring JDBC模板,我們可以說:
- 擁有良好的支持 :在Internet上進行的任何搜索都將導(dǎo)致包含提示和錯誤修復(fù)的多個頁面。
- 許多公司都在使用它 :全世界有幾個項目在使用它
- 對于同一項目,請小心使用不同的數(shù)據(jù)庫:對于使用不同數(shù)據(jù)庫運行的項目,本機SQL可能會成為問題。 需要重寫幾個查詢以適應(yīng)所有項目數(shù)據(jù)庫。
- 框架知識 :很好地了解Spring基礎(chǔ)知識,如何配置和使用它。
對于那些不知道Spring有幾個模塊的人,在您的項目中可以僅使用JDBC Template模塊。 您可以保留項目的所有其他模塊/框架,并僅添加運行JDBC模板所需的模塊/框架。
MyBatis
MyBatis(以iBatis名稱創(chuàng)建)是一個非常好的框架,許多開發(fā)人員都在使用它。 有很多功能,但是我們在這篇文章中只會看到一些。 該頁面的代碼可以在這里找到: https : //github.com/uaihebert/MyBatisCrud
要使用MyBatis運行項目,您將需要實例化會話工廠。 這很容易,文檔說明該工廠可以是靜態(tài)的:
當(dāng)使用MyBatis運行項目時,只需要實例化一次Factory,這就是為什么它使用靜態(tài)代碼。 配置XML(mybatis.xml)非常簡單,其代碼可以在下面找到:
映射器(上面XML中的一個屬性)將保存有關(guān)項目查詢以及如何將數(shù)據(jù)庫結(jié)果轉(zhuǎn)換為Java對象的信息。 可以用XML或接口創(chuàng)建映射器。 讓我們看下面在文件crud_query.xml中找到的Mapper:
請注意,該文件很容易理解。 找到的第一個配置是ResultMap ,它指示查詢結(jié)果類型,并且結(jié)果類配置為“ uai.model.Customer ”。 在該類中,我們有一個具有不同名稱的數(shù)據(jù)庫表列的屬性,因此我們需要向ResultMap添加配置。 所有查詢都需要一個MyBatis會話將使用的ID。 在文件的開頭,可能會看到一個聲明的名稱空間 ,它用作Java包,該包將包裝所有查詢和XML文件中的ResultMap 。 我們也可以使用Interface + Annotation代替XML。 在crud_query.xml文件中找到的Mapper可以轉(zhuǎn)換為以下接口:
在接口中只編寫了Read方法,以使代碼更小,但是所有CRUD方法都可以在接口中編寫。 首先讓我們看看如何執(zhí)行XML文件中的查詢:
對象的解析是自動的,該方法易于閱讀。 要運行查詢,只需使用上面在crud_query.xml代碼中看到的“ 名稱空間+查詢ID ”組合。 如果開發(fā)人員希望使用接口方法,則可以執(zhí)行以下操作:
使用接口查詢模式,我們可以得到干凈的代碼,并且開發(fā)人員無需實例化Interface,MyBatis的會話類即可完成工作。 如果要更新,刪除或在數(shù)據(jù)庫中插入記錄,則代碼很簡單:
關(guān)于MyBatis,我們可以說:
- 優(yōu)秀的文檔 :每當(dāng)我有疑問時,只要閱讀其站點文檔就可以回答
- 靈活性 :允許XML或Interfaces + Annotations,該框架為開發(fā)人員提供了極大的靈活性。 請注意,如果選擇接口方法,數(shù)據(jù)庫的可移植性將更加困難,那么使用部署工件而不是接口來選擇要發(fā)送的XML更容易。
- 集成 :與Guice和Spring集成
- 動態(tài)查詢 :允許在運行時中創(chuàng)建查詢,例如JPA條件。 可以在查詢中添加“ IF”來確定將在查詢中使用哪個屬性
- 事務(wù) :如果您的項目未使用Spring的Guice,則需要手動控制事務(wù)
索莫拉
Sormula是一個ORM開源框架,非常類似于JPA / Hibernate。 此頁面中項目的代碼可以在以下位置找到: https : //github.com/uaihebert/SormulaCrud
Sormula有一個名為Database的類,它的工作方式類似于JPA EntityManagerFactory , Database類就像數(shù)據(jù)庫和模型類之間的橋梁。 為了執(zhí)行SQL動作,我們將使用Table類,該類的工作方式類似于JPA EntityManager ,但是鍵入了Table類。 要以代碼運行Sormula,您將需要創(chuàng)建一個數(shù)據(jù)庫實例:
要創(chuàng)建數(shù)據(jù)庫實例,我們需要的是Java連接。 從數(shù)據(jù)庫讀取數(shù)據(jù)非常容易,如下所示:
您只需要創(chuàng)建一個數(shù)據(jù)庫實例和一個表實例即可執(zhí)行各種SQL操作。 我們?nèi)绾斡成渑c數(shù)據(jù)庫表列名稱不同的類屬性名稱? 看下面:
我們可以使用批注在我們的類中進行數(shù)據(jù)庫映射,非常類似于JPA樣式。 要更新,刪除或創(chuàng)建數(shù)據(jù)庫中的數(shù)據(jù),您可以執(zhí)行以下操作:
關(guān)于Sormula,我們可以這樣說:
- 擁有良好的文檔
- 易于設(shè)置
- 在maven存儲庫中找不到它,如果需要,它將使附加源代碼更加困難
- 有很多檢查過的異常,您需要對調(diào)用的動作進行try / catch
sql2o
該框架可與本機SQL一起使用,并使將數(shù)據(jù)庫數(shù)據(jù)轉(zhuǎn)換為Java對象更加容易。 此頁面中項目的代碼可在以下位置找到: https : //github.com/uaihebert/sql2oCrud sql2o具有一個非常易于創(chuàng)建的Connection類:
請注意,我們有一個靜態(tài)Sql2o對象,它將像Connection工廠一樣工作。 要讀取數(shù)據(jù)庫數(shù)據(jù),我們將執(zhí)行以下操作:
請注意,我們已編寫了本機SQL,但已命名參數(shù)。 我們沒有使用像'?1'這樣的位置參數(shù),而是給像':id'這樣的參數(shù)命名。 可以說,命名參數(shù)的優(yōu)點是我們不會在具有多個參數(shù)的查詢中迷失; 當(dāng)我們忘記傳遞某些參數(shù)時,錯誤消息將告訴我們?nèi)鄙俚膮?shù)名稱。
我們可以在查詢中告知具有不同名稱的列的名稱,無需創(chuàng)建Mapper / RowMapper。 使用查詢中定義的返回類型,我們將不需要手動實例化該對象,sql2o將為我們完成該操作。 如果要更新,刪除或在數(shù)據(jù)庫中插入數(shù)據(jù),可以執(zhí)行以下操作:
這是一個“非常易于使用”的框架。 關(guān)于sql2o,我們可以這樣說:
- 易于處理標量查詢 :SUM,COUNT函數(shù)的返回值易于處理
- 查詢中的命名參數(shù) :使用許多參數(shù)將易于處理SQL
- 綁定函數(shù) :bind是一個將通過給定對象自動填充數(shù)據(jù)庫查詢參數(shù)的函數(shù),不幸的是,由于枚舉問題,該函數(shù)不適用于該項目。 我沒有調(diào)查問題,但是我認為這很容易處理
OO
jOOQ它是一個由很多人指示的框架,該框架的用戶在很多站點/論壇中都贊揚它。 不幸的是,jOOQ在我的PC上無法工作,因為我的數(shù)據(jù)庫太舊了,寫這篇文章時(在飛機上)我無法下載其他數(shù)據(jù)庫。
我注意到,要使用jOOQ,您將需要基于模型生成幾個jOOQ類。 jOOQ在站點上有一個很好的文檔,其中詳細介紹了如何生成這些類。
jOOQ對于使用免費數(shù)據(jù)庫(例如:MySQL,Postgre等)的用戶免費。對于使用付費數(shù)據(jù)庫(例如,Oracle,SQL Server等)的用戶,需要jOOQ付費版本。
- www.jooq.org/
阿瓦耶
是在多個博客/論壇中引用的框架。 它與ORM概念一起使用,并且很容易執(zhí)行數(shù)據(jù)庫CRUD操作。
我發(fā)現(xiàn)的問題:
- 沒有足夠詳細的文檔 :其Hello World不太詳細
- 配置 :它具有必需的屬性配置文件,其中包含許多配置,對于那些只想做一個Hello World的人來說確實很無聊
- 需要增強器:增強是一種用于優(yōu)化類字節(jié)碼的方法,但是一開始很難設(shè)置,并且必須在Hello World之前進行
- www.avaje.org
原始的JDBC方法值得嗎?
JDBC的優(yōu)點是:
- 最佳性能 :在持久層和數(shù)據(jù)庫之間,我們將沒有任何框架。 我們可以使用原始JDBC獲得最佳性能
- 控制SQL :書面SQL是將在數(shù)據(jù)庫中執(zhí)行SQL,沒有框架會編輯/更新/生成查詢SQL
- 本機資源 :我們可以毫無問題地訪問所有本機數(shù)據(jù)庫資源,例如:函數(shù),存儲過程,提示等
缺點是:
- 詳細代碼 :收到數(shù)據(jù)庫查詢結(jié)果后,我們需要手動實例化并填充對象,并調(diào)用所有必需的“設(shè)置”方法。 如果我們具有一對多的類關(guān)系,則此代碼將變得更糟。 在另一個片刻之內(nèi)找到片刻很容易。
- 易碎代碼 :如果數(shù)據(jù)庫表列更改其名稱,則必須編輯使用該列的所有項目查詢。 一些項目使用帶有列名的常量來完成此任務(wù),例如Customer.NAME_COLUMN ,通過這種方法,表列名的更新會更容易。 如果將列從數(shù)據(jù)庫中刪除,即使您具有列常量,所有項目查詢都將被更新。
- 復(fù)雜的可移植性 :如果您的項目使用多個數(shù)據(jù)庫,則必須為每個供應(yīng)商編寫幾乎所有查詢。 對于任何查詢中的任何更新,都必須更新每個供應(yīng)商查詢,這可能需要開發(fā)人員花費大量時間。
我只能看到一個因素,幾乎可以讓我立即選擇原始的JDBC方法:
- 性能 :如果您的項目需要每分鐘處理數(shù)千個事務(wù),需要可伸縮且內(nèi)存使用率低,這是最佳選擇。 通常,中型/大型項目具有所有這些高性能要求。 也可以為項目提供混合解決方案。 大多數(shù)項目存儲庫(DAO)將使用框架,而只有一小部分將使用JDBC
我非常喜歡JDBC,我已經(jīng)工作過并且仍在使用它。 我只是要求您不要認為JDBC是解決每個問題的靈丹妙藥。
如果您知道此處沒有列出的其他優(yōu)點/缺點,請告訴我,我將在此添加您的功勞。
如何選擇正確的框架?
如果要為其他項目更改JPA,或者僅在尋找其他持久性框架,我們必須小心。 如果第3頁中的解決方案不能解決您的問題,最好的解決方案是更改持久性框架。 在更改持久性框架之前,您應(yīng)該考慮什么?
- 文檔 :該框架是否有據(jù)可查? 很容易理解它是如何工作的,它可以回答您的大多數(shù)疑問嗎?
- 社區(qū) :框架是否具有活躍的用戶社區(qū)? 有論壇嗎?
- 維護/修復(fù)錯誤 :框架是否正在接受提交以修復(fù)錯誤或接受新功能? 是否正在創(chuàng)建修訂版本? 哪個頻率?
- 尋找一個了解這個框架的開發(fā)人員有多難 ? 我認為這是要考慮的最重要的問題。 您可以將世界上最好的框架添加到您的項目中,但是如果沒有開發(fā)人員知道如何操作框架,框架將無用。 如果您需要聘請高級開發(fā)人員,找到一名開發(fā)人員會有多難? 如果您緊急需要雇用一個知道未知框架的人員,這可能會非常困難。
最后的想法
我會再說一遍:我不認為JPA可以/不應(yīng)該應(yīng)用于世界上每個項目中的每種情況。 我認為JPA像其他任何框架一樣都有缺點,因此沒有用。
如果您的框架未在此處列出,我不希望您受到冒犯,也許我用來查找持久性框架的研究用語并沒有帶我進入您的框架。
希望這篇文章對您有所幫助。 如果您有任何重復(fù)/問題,請將其發(fā)布。 再見!
翻譯自: https://www.javacodegeeks.com/2014/09/jpa-hibernate-alternatives-what-can-i-use-if-jpa-or-hibernate-is-not-good-enough-for-my-project.html
hibernate jpa
創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎總結(jié)
以上是生活随笔為你收集整理的hibernate jpa_JPAHibernate替代方案。 如果JPA或Hibernate对于我的项目而言不够好,该怎么办?...的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 网易、集英社合作手游《unVEIL th
- 下一篇: HttpClient 4 API –获取