ORM “殺器”之 JOOQ


ORM “殺器”之 JOOQ

JOOQ是啥?

JOOQ 是基於Java訪問關系型數據庫的工具包,輕量,簡單,並且足夠靈活,可以輕松的使用Java面向對象語法來實現各種復雜的sql。對於寫Java的碼農來說ORMS再也熟悉不過了,不管是Hibernate或者Mybatis,都能簡單的使用實體映射來訪問數據庫。但有時候這些 ‘智能’的對象關系映射又顯得笨拙,沒有直接使用原生sql來的靈活和簡單,而且對於一些如:joins,union, nested selects等復雜的操作支持的不友好。JOOQ 既吸取了傳統ORM操作數據的簡單性和安全性,又保留了原生sql的靈活性,它更像是介於 ORMS和JDBC的中間層。對於喜歡寫sql的碼農來說,JOOQ可以完全滿足你控制欲,可以是用Java代碼寫出sql的感覺來。就像官網說的那樣 :

get back in control of your sql

maxwon_chuangtong

(圖片來自http://www.jooq.org/)

 

這貨有啥優點

JOOQ 目前在國內還是很小眾,第一次聽說這玩意還是通過stream 大神的推薦。對於從SSH成長起來的猿類來說,心里也會質疑 “這玩意用的人那么少,靠不靠譜” ,“會不會有很多坑要踩”。通過對着官方文檔寫了幾個demo,頓時心生敬畏,一個念頭沖到腦袋 ” 這東西一定會火”,於是果斷在項目中使用。在使用過程中也會遇到各種小問題,通過幫助手冊和DEMO都能最終解決。相對於Hibernate或者其他ORMS的,JOOQ的編程模式有很大不同,強大的Fluent API使用起來非常方便和流暢。現在我們的項目(MaxWon)使用JOOQ已經在生產環境運行了很長的一段時間,從來沒花太多時間折騰在數據訪問層上面。對於開發來說感受最深的就是這貨真的很簡單很靈活,正如文章標題那樣,這是一個‘殺器’。下面是我總結的幾點,個人愚見。

  • DSL(Domain Specific Language )風格,代碼夠簡單和清晰。遇到不會寫的sql可以充分利用IDEA代碼提示功能輕松完成。
  • 保留了傳統ORM 的優點,簡單操作性,安全性,類型安全等。不需要復雜的配置,並且可以利用Java 8 Stream API 做更加復雜的數據轉換。
  • 支持主流的RDMS和更多的特性,如self-joins,union,存儲過程,復雜的子查詢等等。
  • 豐富的Fluent API和完善文檔。
  • runtime schema mapping 可以支持多個數據庫schema訪問。簡單來說使用一個連接池可以訪問N個DB schema,使用比較多的就是SaaS應用的多租戶場景。

如何使用

具體怎么使用官網文檔說的其實已經很詳細了,愛學習的同學可以參閱一下。下面我根據實際項目中使用的過程講述JOOQ的入門使用方法。

環境
描述 名稱
平台 JDK 1.8
maven 3.3.9
JOOQ 3.7.3
RDS Mysql 5.7
mysql-connector 5.1.39

maven依賴配置如下:

 

代碼生成

目前官方提供了通過java org.jooq.util.GenerationTool來生成映射代碼,但過程還是有點繁瑣,這里就不演示了。還好萬能的maven插件幫助我們解決了這個問題。

配置目標數據庫schema信息后運行

如果一切順利的話,在項目目錄下會看到JOOQ自動生成的代碼

jooqgenrator

使用數據庫的schema信息,JOOQ會自動生成對應的Java Record,這樣就可以使用Record來操作對應的數據庫和表,不需任何其他的關系映射配置。

下面展示使用JOOQ 增刪改查的例子

首先根據mysql connection 信息構造DSLContext,然后使用它來對數據庫進行增刪改查操作。對於具體方法我就不解釋了,懂一點sql我相信都應該能看懂。

上面例子可以窺探出JOOQ DSL 語法風格以及JOOQ的基本使用方法,通過代碼可以so easy 的在腦子里映射出對應的sql語句,感覺就像直接寫sql一樣。但JOOQ和sql不同之處在於它保證了你寫的sql語法正確性和類型安全,如果配上IDEA代碼提示功能,那就更加完美了,再難寫的sql只要 . 一下就會有完整的代碼提示。

查看DSL類源碼看以看到里面大概有14000多行代碼,都是靜態方法,里面包含JOOQ支持的各種DB操作。對於常用的的場景使用DSLContext一般都能滿足需求,但是對於是一些復雜的需求,如創建一個臨時表,column別名,table別名,schema 動態設置,就必須使用DSL來進行操作。

JOOQ最令人滿意的就是在實際使用過程中解決問題的靈活性。下面將展示獲取商品(prodcut)和商品評論(comment)總量邏輯。product 和comment 是通過product_id 關聯。

直接上碼

下面是原生sql的版本

通過上面代碼的對比可以看出JOOQ既享受了Java封裝帶來的便捷又保留了原生sql的靈活。

集成數據源

目前流行的數據源DHCP和c3p0大家都很熟悉了,沒啥講的。我們的項目使用的是阿里的 Druid,它是一個用於實時查詢和分析的高容錯、高性能開源分布式系統,旨在快速處理大規模的數據,並能夠實現快速查詢和分析。下面就以Druid為例演示把數據源綁定到JOOQ中

添加maven依賴

還是上面的JOOQTest demo,只需要重寫getDSLContext 方法

具體Druid配置可以參考官方文檔。

事務

JOOQ 官方提供了 TransactionProvider 對事務的支持,只需要在創建DSLContext的時候設置一下。代碼如下:

下面展示事務的使用

沒錯就這么簡單,只需要把需要用事務的代碼包在transaction里面,假如有異常發生,業務會自動回滾。需要注意一點的是必須使用configuration 重新構建context,要不然不會生效,這也是我為什么沒有使用官方提供的事務管理器。正常的項目中一個業務需要組合若干個service 方法來完成,而官方提供的默認事務管理器就需要把所有業務寫在一個方法中,這在實際應用中顯然是不合理的。幸好JOOQ抽象了事務管理,這樣我們就可以集成第三方的事務管理器。

以大家都熟悉的Spring事務管理器為例。添加依賴

 

 

集成完后 transaction 測試方法就可以這樣寫了

 

其他特性

JOOQ還有很多其他有意思的特性 如對其他語言的支持,數據導出,存儲過程,JPA支持等等,感興趣的可以參閱一下文檔。說到文檔,不得不說開發者對JOOQ的用心,簡單、詳細、美觀是最直接的感受,並且還有豐富的demo示例,對於編程新手來說上手使用也是手到擒來。

下面我就抱磚引玉,通過demo簡單介紹一下ExecuteListener 的使用。ExecuteListener 可以看作是一個JOOQ執行的觀察者,它可以監控SQL執行的整個生命周期。並且可以通過執行上下文,做一些個性化的操作。下面SlowQueryListener類的作用就是收集sql執行過程的慢查詢日志。

在初始化DSLContext 的時候把SlowQueryListener配置進去 代碼如下:

執行時間超過1s的sql,會打印如下日志

 

寫在最后

對於在國內占了大半邊天的Hibernate/Mybatis,JOOQ還是一個小清新,很多人對它都還陌生。通過上面的簡單介紹,也許對你有一點幫助。無論是強大的數據轉換能力還是處理業務的靈活性,簡潔性,都會帶來一些不一樣的體驗。如果你已經厭倦了ORMS的開發模式,正好又接手一個新的項目,JOOQ也許是一個不錯的選擇。

 

作者信息

本文系力譜宿雲 LeapCloud旗下MaxLeap團隊_數據服務組 成員:馬傳林【原創】

– 力譜宿雲 LeapCloud 首發 –

馬傳林,從事開發工作已經有多年。當前在MaxLeap數據服務組擔任開發工程師,主要負責MaxWon服務器開發。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM