将jOOQ与JDBC比较
本文是我們學院課程的一部分,標題為jOOQ –類型安全的數據庫查詢 。
在SQL和特定關系數據庫很重要的Java應用程序中,jOOQ是一個不錯的選擇。 當JPA / Hibernate抽象過多,JDBC過多時,這是一種替代方法。 它顯示了一種現代的領域特定語言如何可以極大地提高開發人員的生產率,從而將SQL內部化為Java。
在本課程中,我們將看到如何使用jOOQ有效地查詢數據庫。 在這里查看 !
目錄
1.簡介 2.檢查異常1.簡介
也可以從org.jooq.academy.section3包中獲得本節中顯示的示例 。
大多數Java開發人員對JDBC是什么以及它如何工作都有深刻的了解。 如果還沒有的話,請查看Oracle的官方JDBC教程以了解有關JDBC的更多信息。
JDBC通常因冗長而受到批評。 JDBC也因選擇了錯誤的“默認值”而受到批評,例如,默認的結果集的延遲實現。 我們將看到jOOQ如何改進這些批評:
2.檢查異常
Java的檢查異常已被視為失敗,這也是Java 8的新Streams API和所有相關功能接口不再支持檢查異常的原因。
jOOQ的所有API都將拋出從jOOQ的org.jooq.exception.DataAccessException派生的RuntimeExceptions ,在大多數情況下您無需捕獲它,從而使其中止當前的正在運行的事務。 比較兩者的示例:
JDBC
// These two calls can throw a SQLException try (PreparedStatement stmt = connection.prepareStatement("SELECT FIRST_NAME FROM AUTHOR");ResultSet rs = stmt.executeQuery()) {// This can throw a SQLExceptionwhile (rs.next()) {// This can throw a SQLExceptionSystem.out.println(rs.getString(1));} }OO
DSL.using(connection).select(AUTHOR.FIRST_NAME).from(AUTHOR).fetch().forEach(record -> System.out.println(record.getValue(AUTHOR.FIRST_NAME)));3.結果集
JDBC的ResultSet是一個非常有狀態的對象,無法與Java collections API很好地互操作。 例如,它沒有實現Iterator ,因為它還必須適應在基礎數據庫游標中向后滾動-幾乎任何人都不需要的功能。
jOOQ通過org.jooq.Result類型更好地集成了SQL結果集,可容納所有用例的95%:
- jOOQ的Result實現了java.util.List ,因此繼承了List的所有功能,包括將其轉換為Java 8 Stream的功能 。
- jOOQ的Result已完全實現到Java內存中,而不是默認情況下是惰性的。 這樣可以盡早釋放資源。
- jOOQ的Result知道其自己的Record類型,該類型允許通過列引用而不是列索引進行類型安全的訪問記錄屬性。
請注意,以上是默認設置。 如果您有較大的結果集,并且不想逐條記錄地實現,則可以始終使用jOOQ的惰性獲取功能。 在以下示例中可以看出:
您可以在foreach循環中使用jOOQ結果
for (Record record : DSL.using(connection).select().from(AUTHOR).fetch()) {System.out.println(record); }您可以將jOOQ結果與Java 8流一起使用
DSL.using(connection).select().from(AUTHOR).fetch().stream().flatMap(record -> Arrays.stream(record.intoArray())).forEach(System.out::println);4.準備的陳述
奇怪的是,JDBC區分靜態java.sql.Statement類型和java.sql.PreparedStatement類型。 這種做法將使您不必執行往返數據庫的操作即可在執行之前準備語句-但是,無論如何,最好使用準備好的語句來執行所有查詢的95%,所以為什么要打擾呢?
jOOQ不會通過單獨的語句類型來區分這兩種執行模式 。 相反,您可以使用設置標志來指示在真正需要時應執行靜態語句。 一個例子:
JDBC
// Static statement try (Statement stmt = connection.createStatement()) {// Remember to pass the SQL string here!stmt.executeUpdate("ALTER TABLE ..."); }// Prepared statement try (PreparedStatement stmt = connection.prepareStatement("SELECT * FROM ... ")) {// Remember not to pass the SQL string here!stmt.executeUpdate();// ... although, from an API perspective, this would be possible toostmt.executeUpdate("Some SQL here"); }OO
// Static statement DSL.using(connection, new Settings().withStatementType(StatementType.STATIC_STATEMENT)).fetch("SELECT * FROM AUTHOR")// Prepared statement DSL.using(connection).fetch("SELECT * FROM AUTHOR")5.帶有結果集的語句
另一方面,無法從JDBC語句類型推斷出該語句是否實際上是一個查詢返回結果集,或者它是否將返回許多更新的行,或者什么都不返回。 如果您不知道,則必須運行以下乏味的JDBC代碼:
JDBC
try (PreparedStatement stmt = connection.prepareStatement("SELECT FIRST_NAME FROM AUTHOR")) {// Use the little-known execute() methodboolean moreResults = stmt.execute();// Use the rarely-used do {} while (...) loopdo {// Check first, if there is any ResultSet availableif (moreResults) {try (ResultSet rs = stmt.getResultSet()) {while (rs.next()) {System.out.println(rs.getString(1));}}}else {System.out.println(stmt.getUpdateCount());}}// Repeat until there are neither any more result sets or update countswhile ((moreResults = stmt.getMoreResults()) || stmt.getUpdateCount() != -1); }OO
使用jOOQ,您可以按類型區分兩種類型的語句 :
- org.jooq.Query是具有更新計數且沒有結果的語句
- org.jooq.ResultQuery是帶有結果的語句
只有ResultQuery具有各種fetch()方法:
Query q1 = dsl.query("ALTER TABLE ..."); int rows = q1.execute();ResultQuery<?> q2 = dsl.resultQuery("SELECT * FROM AUTHOR"); Result<?> result = q2.fetch();翻譯自: https://www.javacodegeeks.com/2015/09/comparing-jooq-with-jdbc.html
總結
以上是生活随笔為你收集整理的将jOOQ与JDBC比较的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: tomcat不停机部署_Tomcat中的
- 下一篇: 迭代器生成器可迭代对象_使用迭代器时如何