database preparedstatement教學 - 為什麼使用JPA而不是直接在Java文件上編寫SQL查詢(即直接寫入JDBC)?




statement差異 insert (6)

我一直在讀幾篇文章什麼是JPA (Java Persistent API)和哪些供應商支持它(DataNucleus,JBoss Hibernate等)

我沒有ORM(對象關係映射)的經驗。

到目前為止我所做的是使用DTO和DAO編寫自己的數據庫類。 到目前為止,我對我所擁有的內容感到高興,但我想知道為什麼人們使用JPA而不是包含SQL的Java文件

對我來說,我覺得寫DAO課程就像下面這樣。

public class DAOUsers {
     public void insertNewUser(DTO DtoUser) {
           String query = "INSERT INTO users(username, address) " +
                          "VALUES(DtoUser.username , DtoUser.address)";
           Executor.run(query);
     }

}

我已經了解到JPA使用JPQL,Java持久查詢語言,它對實體對象而不是直接使用db表進行操作。

我的理解(糾正我,如果我錯了)是這裡的實體對象和我的DTO對像一樣(有點像bean嗎?)

但無論如何...... JPA真正有益於在我的文件中編寫純SQL嗎? 看起來像使用JPA所需的註釋並使SQL不可讀對我來說不是很有吸引力..

如果您需要更多說明,請告訴我,我是這個主題的新手,並希望聽到一些意見。


Answers

為什麼使用JPA而不是直接在Java文件上編寫SQL查詢(即直接寫入JDBC)?

某些項目要求工程師更多地關注對像模型,而不是用於訪問數據存儲的實際SQL查詢。 這個問題實際上可以解釋為

為什麼要使用ORM框架?

在不同的環境中可以有不同的答案。

大多數項目都可以從擁有域模型中受益,持久性是第二個問題。 使用JPA(實現)或大多數其他ORM框架,可以將所有實體(即數據庫中的表)建模為Java中的類。 此外,還可以將行為嵌入到這些類中,從而實現行為豐富的域模型。 此模型中的實體可以有多種用途,包括替換DTO以跨層傳輸數據的目的。

也就是說,有些地方的ORM框架可能不是直接適應問題的,特別是當數據模型已經建立時,或者正在使用遺留系統時,將數據庫表映射到Java類是一項非常重要的工作。 在某些情況下,如果需要絕對調整ORM框架生成的SQL,那麼ORM框架通常是不合適的。

相關問題

  1. Java EE架構 - 在使用像JPA 2這樣的ORM時,仍然建議使用DAO嗎?
  2. 使用ORM還是純SQL?
  3. ORM與手動編碼數據訪問層

如果操作正確,您可以使用JPA實現(如hibernate)將SQL查詢直接映射到java對象。 我最近做了一個項目,我有一個POJO和3或4個註釋和一點點設置代碼來獲取存儲過程並將其直接映射到對象列表(POJO類類型)。 這對我來說是JPA力量的一部分。

如果您使用它就像直接使用SQL + JDBC那麼我不知道有什麼優勢。

這裡有一篇關於JPA優勢的文章。

希望這可以幫助。


眾所周知,對像是我們生活中最重要的東西之一,在編程對像中是簡化任何問題的簡單方法....如果對象可用,那麼為什麼我們使用整個東西而不是那個小部分事物意味著對象....

  • 如果您在企業應用程序中手動編寫SQL語句,則需要花費大量的開發時間來更新和維護持久層。

在持久性方面,==>不再需要JDBC API來進行結果集或數據處理。 ==>它有助於減少代碼行,&&&&&&==>它將我們的應用程序從基礎SQL數據庫和sql方言中抽像出來。 切換到其他SQL數據庫需要在Hibernate配置文件中進行少量更改(一次寫入/隨處運行)。


雖然這是一個老問題,但我覺得它值得一個新的答案。 我是JPA的後期採用者,我已經使用它幾年了,雖然我有一段時間對新應用程序的簡單性感到印象深刻,但我已經變得毫無印象具有正確執行JPA所需的性能,複雜性和學習曲線。 這個帖子的答案實際上強化了我的立場。

首先,@ chicket建議“實體可以有多種用途”......我在生產中看到過這種情況,我會說ORM會鼓勵它。 凝聚力和單一責任原則。 根據我的經驗,向數據庫實體添加行為是一件麻煩事。 我知道這是因為我已經做到了,並且後悔了。

其次,JPA的複雜性有一些簡單的替代方法,它們能夠使用具有RDBMS的類,而不會由於ORM嘗試(不成功)解決的不匹配而導致的所有沉重(和性能問題)。 我們在具有超過1,000個表的應用程序中使用非JPA關係類映射工具已有十年了,我們根本看不到JPA如何通過更直接的數據庫訪問來改進。 JPA模糊了數據庫的功能,同時將開銷(以註釋和JQL的形式)添加到類模型中...不應該以其他方式工作嗎?

@water提出了許多在理論上是真實但在現實中不切實際的事情。 例如,我已經三次切換後端數據庫,我可以向讀者保證,沒有一些配置調整,你就完成了。 我建議,如果你花了很多時間維護你的持久層,你的數據庫模型正在發展,你將在JPA中做相同或更多的工作。 特別是當JPA中的非平凡查詢需要使用JQL時!

幾乎每個人都假裝JPA開發人員不需要知道SQL。 我在實踐中看到的是,現在我們必須學習SQL JQL。 顯然我們不需要做DDL - 但是在任何非平凡的應用程序當然你需要知道DDL。 Hibernate甚至不建議使用自動DDL生成。 顯然我們不需要做DML,除非我們調用Native Query,當然這是不可移植的,破壞了緩存,並且與JDBC有著同樣的問題......

最終,在一個結構合理的應用程序中,域模型獨立於業務邏輯,JPA幾乎沒有提供功能,因為我發現這是一個非常高的學習曲線 - 因為域模型實際上非常容易構建。 我不會直接使用JDBC,但是像Apache DBUtils這樣的東西在JDBC之上提供了一個簡單的層,它將行映射到對象,並且通過一些努力可以提供JPA的大部分優點,沒有任何隱藏,也沒有任何開銷。

我從JDBC 1.0開始使用各種庫(以及JDBC之前的iODBC和ESQL)開發Java數據庫應用程序,僅出於性能原因,我已經完成了JPA。 但即使表現更好,學習曲線和不完整的抽像也會給我帶來嚴重的停頓。 JPA很複雜,並試圖隱藏我認為開發人員實際需要關注的細節。 作為一個例子,我們最近看到hibernate問題250刪除命令到數據庫時,一個就足夠了。 JPA本質上使這種錯誤變得容易。

我不是在倡導JDBC,我只是在提倡反對JPA。 不能或不能在SQL中工作的開發人員可能不應該編寫關係應用程序 - 比像我這樣的開發人員,不能用矩陣代數來挽救我的生命,應該是編寫3D遊戲。 那些使用SQL謀生的開發人員應該為扭曲的SQL而感到震驚,因為它會向服務器發送休眠狀態,以避免一開始就不需要的往返。


JPA在我的文件中編寫純SQL的真正好處是什麼?

以下是一些好處:

  • JPA允許您避免在SQL的數據庫特定方言中編寫DDL。 相反,您可以在XML中編寫“映射”,或使用Java註釋。

  • JPA允許您避免在SQL的數據庫特定方言中編寫DML。

  • JPA允許您在沒有任何DML語言的情況下加載和保存Java對象和圖形。

  • 當您確實需要執行查詢時,JPQL允許您根據Java實體而不是(本機)SQL表和列來表達查詢。

一般來說,JPA比JDBC + SQL +手寫映射更簡單,更清晰,勞動強度更低。 數據模型越複雜,它就越有益。

但是,如果性能是最重要的考慮因素,JPA確實會通過在應用程序和數據庫之間添加層來阻礙性能。 如果您的應用程序要求您廣泛手動優化本機數據庫查詢和模式以最大限度地提高性能,那麼JPA可能不太合適。

如果你在同一個應用程序中更好地處理 Java,JDBC和SQL,那麼JPA可能也不適合你,而不是讓ORM處理凌亂的細節。 (但如果你是,你可能是少數......)


不,但是它們使用代理和反射來偽造:

  public static class TestClass {
      public String knockKnock() {
          return "who's there?";
      }
  }

  private final TestClass testInstance = new TestClass();

  @Test public void
  can_delegate_a_single_method_interface_to_an_instance() throws Exception {
      Delegator<TestClass, Callable<String>> knockKnockDelegator = Delegator.ofMethod("knockKnock")
                                                                   .of(TestClass.class)
                                                                   .to(Callable.class);
      Callable<String> callable = knockKnockDelegator.delegateTo(testInstance);
      assertThat(callable.call(), is("who's there?"));
  }

這個習慣用法的好處在於,您可以在創建委託人的時候驗證委託方法是否存在,並且具有所需的簽名(儘管不是在編譯時,但不幸的是,儘管FindBugs插件可能會幫助這裡),然後安全地使用它委託給各種實例。

查看github上karg代碼以獲取更多testsimplementation





java database orm jpa