jOOQ 項(xiàng)目存在的原因
以下段落摘自 jOOQ用戶手冊的前言部分。值得思考的是,為什么你應(yīng)該(或者不應(yīng)該)在某特定項(xiàng)目中使用JOOQ。具體講,你可能正要從jOOQ 和JPA,或者jOOQ和Hibernate,或者jOOQ和QueryDSL、或者jOOQ和SLICK(對Scala而言)的兩者之中選擇其一。這里給出一些指導(dǎo)原則(當(dāng)然會稍微有點(diǎn)偏向JOOQ):
jOOQ存在的理由 —— 同JPA相比
Java和SQL在一起使用已經(jīng)有很久了。SQL是一種很“古老”但很完備的技術(shù),大家對它的理解也已很透徹。雖然在Java的運(yùn)行平臺JVM之上也能建立一些新式的當(dāng)代語言,但Java語言可也不算新了。然后,經(jīng)過了這么多年,處理SQL和Java二者之間接口的庫(Library)不斷變來變?nèi)ィ涣粝铝薐PA這個(gè)大家勉強(qiáng)在半信半疑中接受的一個(gè)標(biāo)準(zhǔn), 幾乎沒留下任何別的選項(xiàng)。
迄今為止,能夠真正把SQL看做編程語言當(dāng)中具有首要地位的數(shù)據(jù)庫抽象框架或庫,少之又少。包括業(yè)界標(biāo)準(zhǔn)JPA, EJB、Hibernate、JDO、Criteria Query以及其它很多在內(nèi)的框架,為將SQL的使用范圍縮減到最小采用了JPQL、HQL、JDOQL以及其它各種各樣的低級查詢語言,它們都是在企圖隱藏SQL本身。
jOOQ來填補(bǔ)這一空白。
jOOQ存在的理由 —— 同LINQ相比
為了更好地將查詢作為一個(gè)概念集成到編程語言當(dāng)中,其它的平臺采用了LINQ (同LINQ-to-SQL一起), Scala用的是SLICK,Java也采用了QueryDSL。通過查詢,它們可以理解對任意目標(biāo)的查詢,這些目標(biāo)可以是SQL、XML、集合(Collection)以及其它的異構(gòu)數(shù)據(jù)存儲(Data Store)。JOOQ斷言,這樣也是走錯(cuò)了方向。
在比較高級的查詢用例中(比簡單的CRUD和少量的多表查詢高級),人們還是希望能夠從SQL較強(qiáng)的表達(dá)能力中獲益。SQL本身的關(guān)系型特質(zhì),使得它和C#、Scala或者Java等等這類面向?qū)ο笳Z言和非完全函數(shù)式編程語言能夠做到的事情相比,差別巨大。
要用形式化的方式表達(dá)和驗(yàn)證它們產(chǎn)生的多表查詢和臨時(shí)表(ad-hoc)的表達(dá)式的類型非常困難。要想支持類似數(shù)據(jù)透視表(Pivot Table)、非巢套式游標(biāo)(Unnested Cursor)或者僅僅是從派生表中進(jìn)行任意投射(Projection)等等這樣高級的表表達(dá)式,那就更加是難上加難了。如何在非常強(qiáng)的面向?qū)ο箢愋湍P椭袑?shí)現(xiàn)這些特性,不太可能會在考慮范圍之內(nèi)。
本質(zhì)上講, 決定創(chuàng)建看上去跟SQL或者C#或者Scala、Java很像的API,就是一種確定無疑的或者偏向這個(gè)或者偏向那個(gè)平臺的決定。盡管讓SLICK以和LINQ(或者Java世界里的QueryDSL)類似的方式進(jìn)行演進(jìn)比較容易, 但是隨后,用以清晰表達(dá)其背后意圖的SQL特性范圍(Feature Scope)就很難再添加進(jìn)來了(比如,你怎么來對Oracle的分區(qū)外聯(lián)語法進(jìn)行建模?如何對ANSI/ISO SQL:1999中的分組集(Grouping Set)進(jìn)行建模?怎樣才能支持標(biāo)量子查詢緩存?等等問題)。
jOOQ來填補(bǔ)這個(gè)空白。
jOOQ很不同
SQL從來就不是一種抽象的語言。它不局限在重量級的映射器這樣狹小的范圍之內(nèi),也不隱藏關(guān)系型數(shù)據(jù)的美以及簡單性。SQL一直都不面向?qū)ο?。SQL從來就不是SQL之外的任何其它東西!