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