JDO 2.0查詢語言的特點_JSP編程

來源:互聯網
上載者:User

  查詢語言的改進是JDO2.0規範中的重要環節,本文從較高的層面闡述JDO2.0所提供的一些新功能。由於JDO2.0規範還未進入公開草案狀態,目前還沒有任何內容敲定下來,一切都還可能面臨變化。不過,JDO2.0將會很快進入最後階段,而這裡提到的查詢特性是JDO2.0專家組(譯者註:David Jordan就是專家組重要成員)花費時間最多,並且相對來說最為穩定。因此,我有足夠理由相信,最終規範與這裡的描述將會基本一致。

  如果各位讀者覺得本文遺漏了某些重要的特性,建議立即到JDO論壇(http://www.jdocentral.com/forums/index.php?showforum=10)去提出並討論。這裡我們需要感謝JDO2.0規範領導人Craig Russell授權給我公開這些JDO2.0查詢語言的新特性。

  查詢結果

  你可以建立一個對A類的查詢,通過contains()引用到B類,再通過又一層contains()引用到C類,最後再使用一個“.”操作符引用到D類。但最終返回的集合中只會包含A類的對象執行個體,如果要從結果中獲得其它類,就必須通過A類的引用來逐個擷取相關的其它類對象。如果你的查詢條件裡麵包含了B、C或D類的約束,那麼在結果集中通過A類對象引用其它類對象時,必須重新將這些約束在Java代碼中重複一遍,也就是說,你不得不在Java和JDOQL中重複聲明限制條件。再者,你可能只關心滿足查詢條件的D類對象,而不希望中間的B、C類對象被JDO底層建立從而節省記憶體或相關資源。

  在JDO2.0中,你再也不受縛於這些限制了。你可以返回:

  資料類(PersistentCapable)的一個或多個欄位
  候選類以外的其它類對象

  統計資料

  這意味著你可以返回A、B、C、D類對象,或者它們的某些欄位,或者二者的混和結果。你還可以計算類似min或max之類的統計結果。基本上,你想返回什麼結果都可以。

  當你建立一個查詢時,你可以指定一個“結果定義(Result Specification)”來指定返回什麼樣的內容。它是一個包含一個或多個以逗號分隔的“結果運算式(Result Expression)”。結果運算式可以是:

  this關鍵字,表示返回候選類的對象執行個體。這與JDO1.0是一樣的欄位,標明候選類或引用類的某個欄位的值,如 address.street.name 欄位運算式,代表對多個欄位進行JDO預定義的幾種算術運算而獲得的結果變數,代表查詢條件中出現的某個中間變數參考資料表達式,也就是JDO1.0中的通過“.”操作符進行的對象之間的引用 統計運算式通過對以上這幾種結果運算式的組合運用,你可以獲得任何你想要的結果。

  JDO2.0支援下面的統計函數:

  count(運算式),運算式可以是this
  sum(數字型欄位運算式),“數字型欄位運算式”可以是通過欄位或欄位的運算得到的數字型的結果
  min(數字型欄位運算式)
  max(數字型欄位運算式)
  avg(數字型欄位運算式)

  對查詢結果的指定是通過下面的API:

  void javax.jdo.Query.setResult(String result)

  如果你不調用這個方法,或者參數是null,則返回候選類的對象執行個體(相當於設定為“this”),即JDO1.0的返回結果。如果你只指定了唯一結果運算式,則返回集合的元素類型與該結果的類型一致。另外,在預設下,如果指定了多個結果運算式,則返回的集合元素類型將是 Object[]。

  你可以在結果定義字串的開頭標上distinct來保證結果不會重複。而如果結果定義串中包含好幾個運算式,那麼distinct可以保證結果集中不會有重複的資料群組。

  每個結果運算式可以指定一個名稱,對於簡單的欄位,系統會預設以該欄位的名稱作為結果中該項的名稱。對複雜的運算式,你可以使用下面的文法指定名稱:

  result_expression as name
  
  名稱的使用可以讓結果中的該項作為結果類中的一個屬性來進行設定和使用。你可以指定一個結果類(result class),用來返回查詢結果。如果查詢結果是一個單值,結果類可以是任何JDO支援的類(Integer, Double, String, BigInteger, BigDecimal, java.util.Date, java.sql.Date, java.sql.Time, java.sql.Timestamp)。Query中設定結果類的方法是:

  void setResultClass(Class resultClass)


  如果查詢結果包含多個結果運算式,你可以定義一個結果類來保留結果中的各項資料,這個類必須有一個無參數的構造器。此外,每個結果運算式必須對應此類中的一個屬性,不論是一個public的欄位,還是一個public的setXxx()方法,並且這種直接的或bean風格的屬性名稱與查詢結果中各項結果運算式的名稱保持一致。

    組操作(Grouping)

  統計功能可用於一個分組操作中。JDO2.0提供類似SQL中的GROUP BY和HAVING子句。Query方法:


  void setGrouping(String groupSpec)


  用於指定分組的原則。groupSpec參數包含一個或多個以逗號分隔的分組運算式,還可以跟上一個以“having ”開頭的過濾條件。調用此方法後,setResult()參數的每個結果運算式項必須是groupSpec中的一項,或者是groupSpec中的一項或多項的運算結果。所有groupSpec項的值均相同的結果被歸在同一組中(同一條結果記錄)。having子句的過濾條件可以包含boolean結果的判斷語句或者是對分組運算式的統計運算。與SQL一樣,having子句用於對分組後的結果集進行條件過濾。

  唯一性(Uniqueness)

  很多人一直奇怪為什麼Query的執行(execute)結果是一個Object類型的對象,因為這樣給開發人員造成必須手工強制將結果轉換成Collection的不便。JDO1.0中查詢結果一般有多個元素,但JDO專家組計劃在JDO2.0中加入對返回單值結果的查詢的支援,於是將Query的執行結果定義為Object類型。

  你有時會執行一個你確定結果只會有一條的查詢(比如統計總數或者按具有唯一索引的會員帳號尋找對象等等),在JDO2.0中,你可以調用Query方法來聲明:


  void setUnique(boolean unique)


  當你傳入“true”後,Query執行的結果將是一個單獨的值對象,如果無任何結果返回,則結果是null。如果JDO發現查詢結果返回了多條記錄,則會扔出一個異常。

  限制返回結果的大小

  設計使用者介面的時候,我們常常會顯示結果集的某一部分子集(比如分頁顯示或只顯示前十條之類)。為了效能和效率,你多半會需要限制返回結果的範圍。Query的方法可以完成這一點:


  void setRange(int fromInclusive, int toExclusive)


  該方法返回的結果集只包含原結果集的第fromInclusive條到第toExclusive-1條。

  新的過濾條件操作符

  一些新的操作符被加到JDOQL中,以便執行針對引用、Map、字串和數位操作。instanceof操作符返回一個boolean值,可以讓你過濾某個指定類的對象;同樣返回boolean值的containsKey(Object)函數和containsValue(Object)用於訪問Map元素。

  字串處理方面加入了很多函數,toLowerCase()和toUpperCase()分別完成大小寫轉換,另外還有下列函數用於尋找子串位置和獲得子串:


  int indexOf(String)
  int indexOf(String, int) String substring(int) String substring(int,int)


  另外,String的方法:


  boolean matches(String pattern)


  用於執行正則式匹配。目前只能提供有限的匹配功能。“.”和“.*”可表示萬用字元,而“(?i)”表示匹配不區分大小寫。

  對數字型的欄位,JDO2.0增加了兩個函數:


  Math.abs(numeric) Math.sqrt(numeric)


  預定義查詢(Named Queries)

  你可以在JDO描述符(metadata)中聲明常用的JDOQL查詢語句,這樣就不用將查詢嵌入到Java原始碼中。這樣可以提供一些靈活性,比如將查詢語句寫到一個配置好的文字檔中,而需要修改時可以直接改該檔案,而不用更改Java源碼。描述符中的每個查詢都有一個名字,而要執行某個查詢時,可以使用下面的方法來建立查詢:

  Query newNamedQuery(Class cls, String queryName)

  JDO將會搜尋描述符來找到對應的預定義查詢語句並產生相應的Query對象。

  訪問靜態欄位(static fields)

  你將可以在JDOQL中訪問資料類中以public static final方式聲明的常量。比如

  public static final int FEMALE = 0;
  public static final int MALE = 1;
  public static final int UNKNOWN = 2;


  而在查詢中使用類似“salary > 5000.0 && gender == MALE”的過濾條件。

  大量刪除(Deletion by Query)

  在JDO1.0中,要刪除一個對象,必須先將其載入記憶體,再刪除,然而很多情況下,你在刪除之前並不需要訪問該對象,這樣的做法比較低效。在JDO2.0中,提供了Query的幾個方法來刪除符合查詢條件的一組對象:

  Object deletePersistentAll(Object[] parameters) Object deletePersistentAll(Map parameters) Object deletePersistentAll()

  此查詢結果的對象會被全部從資料庫刪除。這些方法返回被刪除對象的集合。你的程式可以決定是否需要對被刪除的對象逐個訪問。如果你不訪問這些對象,Query執行的效能將不會受到任何影響,換句話說,這些對象將不會在記憶體中產生。
  
  廠商擴充的查詢特性

  JDO廠商可以給JDOQL提供各種各樣的特殊查詢功能。每個廠商可以定義一組屬於該廠商自己的擴充功能。如果你需要使用其中的功能,你需要將該廠商的擴充加到程式運行環境中。每個擴充有一個名字和一個可選的值。你可以單獨設定每個擴充,或者一次性設定多個擴充。Query的下列方法用於設定廠商擴充特性:

  void setExtensions(Map extensions) void addExtension(String key, Object value)

  SQL直接存取

  如果JDO2.0的查詢功能不能滿足需要,並且以下條件都滿足:

  你的應用運行在關聯式資料庫上
  
  你需要的查詢有SQL語句可以實現

  你知道從你的類模型到資料庫的映射細節

  你就可以建立一個SQL查詢,方法是調用PersistentManger的方法:

  Query newQuery(String language, Object query)
  
  每一個參數需要設定為“javax.jdo.query.SQL”,而query是一個具體的SQL語句。如果你的查詢需要返回類的執行個體,則這個SQL語句必須返回該類的相應主鍵欄位。使用直接的SQL時,JDOQL提供的函數將不能被使用,否則將會扔出異常JDOUserException,比如,你不能對該Query設定過濾條件字串、排序聲明或變數聲明。使用SQL查詢時,參數都是未指定類型的,在SQL語句中以“?”表示,並且按出現的順序被綁定。

  結束語

  各位讀者已經看到,JDO2.0對查詢語句增加了很多新的功能和特性,我認為其中的查詢結果定義是最大的改進。正如我在文章開頭說的,這一部分變化目前來說是JDO2.0中最穩定的部分,不會有大的變化。廠商可以開始提供很多這樣的功能,不用考慮專家組還在討論的JDO2.0其餘部分將如何變化。

  在JDO2.0提供標準的對象/關係映射的前提下,這裡描述的查詢功能和一個用於多層結構的JDO應用的脫鉤/掛鈎(detach/attach)機制,將使JDO佔領更多的市場。對這一點有深切體會的廠商將不遺餘力地爭取率先推出穩定、完整、高效的JDO2.0產品。JDO將是基於資料庫儲存和管理的應用開發的首先API,開發人員們將享受物件導向的模型設計和高效的資料存放區管理系統。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.