熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> JSP教程 >> 正文

pureQuery帶注釋的方法風格簡介

2013-11-15 11:52:18  來源: JSP教程 

  pureQuery 是一種高性能 Java&#;數據訪問平台其目標主要是簡化數據訪問應用程序的開發和管理它由工具API 和運行時組成本文介紹 pureQuery 帶注釋的方法風格 —— 這是一種簡單靈活的風格屬於命名查詢(namedquery)范例可以靜態或動態地執行 SQL本文先解釋為什麼開發人員要選擇使用帶注釋的方法風格編寫 pureQuery 應用程序再解釋帶注釋的方法風格與 pureQuery 內聯編程風格之間的差異並簡要概述 pureQuery 帶注釋的方法的強大特性

  概述

  本文討論與帶注釋的方法的編程風格相關的以下主題   


描述帶注釋方法的編程風格
選擇使用帶注釋方法編程風格的原因
使用帶注釋的方法風格開發 pureQuery 應用程序的步驟
描述代碼生成給出生成的代碼示例
描述在 pureQuery 接口中定義帶注釋的方法的需求
使用 pureQuery 接口執行 SQL
介紹帶注釋的方法風格的一些選擇特性例如批處理生成的 RowHandlers 和 ParameterHandlers生成的鍵以及使用 XML 配置文件修改代碼生成器的輸出

  如果您已經准備好開始編程那麼可以跳到 技術性崩潰接下來介紹一個簡單的例子展示為什麼開發人員要選擇使用帶注釋的方法風格開發 pureQuery 應用程序

  什麼是帶注釋的方法編程風格?

  為了介紹帶注釋的方法編程風格首先需要理解這兩種 pureQuery 編程風格的背景知識

  內聯編程風格 的開發目的是為了滿足客戶對快捷簡便的編程風格的需求這種風格很容易被熟悉 Java? Database Connectivity(JDBC)的開發人員掌握 —— 其特點就是可以更快更簡單地編程內聯風格最初的目標是減少 JDBC 程序員熟悉的一些重復的編程任務同時提供一個 API工具可以輕松地利用該 API 將數據訪問開發與 Java 開發聯系在一起由於應用程序中定義 SQL 語句的方式這種編程被稱作 內聯在內聯風格中SQL 語句是在運行時聲明或構造的並作為 String 的實例傳遞給公共的 Data 接口方法內聯風格可以最大化編程速度和開發靈活性並支持動態執行後期文章將提供對公共 Data 接口 API 的概述關於內聯風格的更多信息可以在 pureQuery 文檔中找到(參見 參考資料)

  本文主要討論帶注釋的方法編程風格這種風格的演化和內聯編程風格相似但是它還有另外一個目標那就是最大化編寫的 pureQuery 應用程序的可配置性和安全性帶注釋的方法風格是專門為同時支持動態和靜態數據庫訪問而設計的其目的是滿足對類似於 Java Persistence API(JPA)的用於數據訪問的命名查詢編程接口的客戶需求 —— 更快更簡單地編程必要時能夠支持靜態執行

  與內聯編程風格一樣帶注釋的方法也起源於應用程序定義 SQL 語句的方式在帶注釋的方法風格中SQL 字符串被定義為 Java 的一個元素pureQuery AnnotationpureQuery 為此目的定義的方法注釋有 @Select (注釋 SQL 查詢) @Update (注釋 SQL DML 語句)和 @Call (注釋 SQL CALL 語句)這些注釋被放在用戶定義接口內的用戶定義方法聲明中代碼生成器預處理接口為每個已聲明的帶有注釋的方法生成實現代碼生成的實現代碼使用 pureQuery 運行時執行注釋中定義的 SQL 語句在注釋元素中預先定義 SQL 字符串可以簡化靜態執行支持

  Data Studio 對帶注釋的方法風格的工具支持包括一個代碼生成器它可以創建用戶編寫的帶注釋的方法的實現代碼生成的結果就是第二個實現類該實現類被編譯並用於執行初始接口中聲明的 SQL 語句 說明了用戶定義的帶注釋的方法接口代碼生成器和生成的實現類之間的關系

  圖 pureQuery 帶注釋的方法的代碼生成

  

  一個有趣的例子

  本節介紹一個虛構的例子Silver Castles 的數據訪問開發小組Silver Castles 是一家正在不斷發展的公司銷售各種銀制產品該公司正在 Silver Castles 網站上開發一個新的基於 Web 的店面並且已經決定使用 pureQuery 環境來開發數據訪問應用程序的持久層當他們觀看了 pureQuery 工具演示 並閱讀了 pureQuery 教程 之後很快就決定使用 pureQuery他們了解到使用 motivating 快速開發測試和部署用於多平台的基於 Java 的數據訪問持久層非常容易當這個小組決定何時使用帶注釋的方法編程風格何時使用內聯編程風格時還會受到其他一些因素的影響有一個叫做 Bob 的開發人員決定成為帶注釋的方法編程風格方面的專家他收集了一些知識以幫助小組決定何時使用這兩種編程風格後面介紹了這些知識

  決定使用帶注釋的方法

  Bob 首先審視了帶注釋的方法編程風格幾小時後他回到小組並給出一份清單上面列出帶注釋的方法風格的一些亮點

  范例


遵從命名查詢的風格目標是等同或超過現有對象關系映射器和持久化解決方案的功能
鼓勵將持久層(CRUD)語句與應用程序在帶注釋接口中的其余部分分離其結果是開發中對 SQL 語句的更改不會擴散到整個應用程序也不會影響負責其他層的開發人員帶注釋的接口為管理整個應用程序的 SQL 語句提供一個集中控制點
SQL 語句文本是在開發時知道的但是可以提前對 SQL 語句文本進行分析以便開發人員優化輸出對象的分配

  靜態支持


pureQuery 帶注釋的方法編程風格使得執行靜態 SQL 成為一個部署選項而不是設計選項帶注釋的方法代碼可以動態地部署也可以使用 IBM Data Servers 上的靜態 SQL 包來部署而不必修改任何代碼
從應用程序開發人員和前端應用程序的角度透明轉換到靜態執行
選擇針對靜態執行進行部署可以獲得靜態 SQL 的全部好處安全性能監控和預運行時優化

  代碼生成


最小化手動編寫代碼先聲明接口方法簽名和 SQL 語句然後由 pureQuery 代碼生成器產生數據訪問代碼實現
返回查詢結果由 pureQuery 預處理為多種對象例如已填充的 pureQuery bean 的 Iterators或者列名的 Lists或者列值 Maps
要對數據訪問進行預處理和後處理使用 Hook 定制生成的代碼的行為
使用 XML 配置文件 為每個目標數據庫定義不同的 SQL

  開發和使用帶注釋的方法

  下面的清單 顯示了 Bob 編寫的 pureQuery 接口的一部分親自體驗帶注釋的方法風格他使用該接口向小組成員解釋帶注釋的方法風格的基礎pureQuery 帶注釋的接口是帶注釋的方法風格的構建塊pureQuery 接口由以下部分組成


    一個 Java interface 定義包含

      一個或多個方法聲明
      對於每個方法聲明有一個 pureQuery 數據訪問注釋 @Select@Update@Call每個注釋包括一個 SQL 語句其中包含方法被調用時要執行的 SQL 語句(也可以選擇在一個配置文件而不是注釋元素中提供該 SQL 語句)
      對於每個方法聲明有一個 Java 返回類型表明 pureQuery 運行時將數據訪問結果返回給調用者時需要使用的對象格式
      對於每個方法簽名有一些 Java 參數類型包括表明用於執行 SQL 語句的參數的對象類型

  除了以上描述的那些方法聲明或定義外接口定義文件不包含任何其他方法聲明或定義定義好 pureQuery 接口之後應用程序的其他層在概念上可以將該接口當作一個數據庫 —— 可以很容易地通過調用聲明的 Java 數據訪問方法來從 Java 中訪問當另一個應用程序層調用一個帶注釋的方法時它將收到執行相關聯的 SQL 語句的結果形式為一個適當格式化的 Java 對象開發其他應用程序層時不需要 SQL 方面的知識

  清單 pureQuery 帶注釋的方法風格的接口

   package comibmdbpureQuery;

import javautilIterator;
import comibmpdqannotationSelect;

public interface CustomerData {
   // Select all PDQ_SCCUSTOMERs and populate Customer beans with results
   @Select(sql=select CID NAME COUNTRY STREET CITY PROVINCE ZIP PHONE
                      INFO from PDQ_SCCUSTOMER)
   Iterator<Customer> getCustomers();

   // Select PDQ_SCCUSTOMER by parameters and populate Customer bean with results
   @Select(sql=select CID NAME COUNTRY STREET CITY PROVINCE ZIP PHONE
                      INFO from PDQ_SCCUSTOMER where CID = ?)
   Customer getCustomer(int cid);
 
}
    生成一個實現

  定義好上述接口後Data Studio 中的 pureQuery 項目工具自動將它提供給 pureQuery 代碼生成器pureQuery 代碼生成器產生該接口的一個實現放在一個名為 CustomerDataImpljava 的文件中為便於讀者查看清單 中給出了生成的文件注意生成的文件中的所有代碼(清單 )都不是由開發人員手動編寫的

  您不需要查看生成的代碼如果您想看看 Silver Castle 應用程序如何使用以上接口可以跳到 下一步接下來了解更多關於生成的代碼的信息

  代碼生成器和生成的代碼

  代碼生成器以用戶定義的 pureQuery 接口為輸入例如由 SilverCastles 開發人員定義的簡單的 CustomerData它生成的代碼用來執行針對接口中每個方法進行注釋的每個 SQL 語句它還生成用於將結果處理為所聲明類型的代碼生成的代碼調用 pureQuery 運行時來執行每個方法所需的處理

  關於生成的代碼有一些重要的注意事項


生成的元素對於每個聲明的方法生成的元素包括方法定義一個內部 pureQuery StatementDescriptor一個生成的 RowHandler 或 ResultHandler 以及一個內部 pureQuery ParameterHandler
實現類名稱生成的實現文件的名稱以初始的用戶定義接口的名稱為基礎在名稱後面加上 Impl在這個例子中開發人員編寫了 CustomerData 接口代碼生成器產生 CustomerDataImpl 類生成的類實現 CustomerData 接口數據訪問應用程序的其他層不會使用實現類的名稱它們總是引用和使用用戶定義接口但是知道實現文件的名稱還是有用的以便檢查生成的代碼
實現超類除了實現用戶定義接口外生成的實現類還擴展內部的 pureQuery 類 BaseData後者實現外部的 Data 接口這個超類是 pureQuery 運行時的一部分負責處理訪問數據庫和處理結果的固定的重復的操作
看到生成的代碼時不要感到困惑開發人員不需要查看這些代碼除非他們執意要這麼做

  使用帶注釋的方法

  至此項目已經構建完畢Data Studio pureQuery 工具已經調用了 pureQuery 代碼生成器並且接口實現也已經生成並編譯開發人員現在可以通過調用 pureQuery 帶注釋的接口中聲明的帶注釋的方法從應用程序的其他層訪問數據這個過程很簡單應用程序通過發送給 DataFactory 的一個請求實例化 pureQuery 接口的一個實例(概念上的數據庫)然後它調用數據訪問方法如下所示

  清單 調用帶注釋的方法

  
javasqlConnection con = ;

// use the DataFactory to instantiate the CustomerData interface
CustomerData cd = DataFactorygetData(CustomerDataclass con);

// execute the SQL for getCustomers() and get the results in Customer beans
Iterator<Customer> cust = cdgetCustomers();

// the application can now consume the Iterator of Customer beans

  通過幾行代碼就訪問了數據庫執行了所需的 SQL 語句並將結果處理成方便的 Customer 類的數據 bean 的 Iterator因此應用程序可以直接使用更加令人印象深刻的是即使要實現持久層方法開發人員也只需聲明這裡所調用的方法pureQuery 代碼生成器和運行時會處理其余的工作

  分解帶注釋的方法風格

  本節將這個示例分解成帶注釋方法編程風格的幾個重要組成部分pureQuery 文檔包含對這些和其他 pureQuery 編程概念的完整描述(參見 參考資料)

  pureQuery 接口

  在以上例子中用戶定義的 pureQuery 接口被命名為 CustomerData合理地命名接口以反映它所代表的信息源這樣做很有幫助如 Silver Castles 示例一樣例如CustomerData 方法檢索和更新關於公司客戶的信息

  如上所述pureQuery 接口只包含帶注釋的方法的聲明

  帶注釋的方法的聲明

  pureQuery 接口中的每個方法聲明包含以下必要元素


三個 pureQuery 注釋中的一個@Select@Update 或 @Call
對於每個注釋有一個 sql=<string> 元素其中的 string 包含一個有效的 SQL 語句這個 SQL 語句將在方法被調用時執行(可選地也可以在一個 XML 配置文件中提供 SQL 語句)
一個標准的 Java 方法聲明

  已聲明的返回類型

  方法聲明的返回類型表明 SQL 語句的結果返回什麼樣的對象格式取決於所使用的注釋受支持的返回類型有所不同例如對於查詢可以返回各種集合和簡單類型對於更新可以使用標准的更新計數格式除了其他格式外 StoredProcedureResult 返回類型可以方便地封裝存儲過程調用的結果

  還可以由 pureQuery 引擎將結果處理成用戶定義 pureQuery bean 的一個集合在我們的示例中開發人員聲明的返回類型是 Customer bean 的一個 IteratorpureQuery 使用一組 bean 約定和需求 將數據庫查詢結果直接映射到用戶定義的 bean 類pureQuery bean 中的注釋 可以覆蓋默認的映射行為而且可以由用戶提供的 RowHandler 將結果手動映射到 bean否則生成的 RowHandler 將在把 bean 結果返回給調用者之前自動執行默認的映射將結果映射到用戶定義的 bean 類

  聲明的參數類型

  帶注釋的方法聲明中的參數類型決定 pureQuery 如何在運行時獲得 SQL 語句參數值SQL 語句中的參數占位符與帶注釋的方法中聲明的參數之間可能存在一對一的映射但是也不一定如此pureQuery 遵從 參數占位符語法規則 來決定如何從帶注釋的方法的參數列表中聲明的參數映射 SQL 語句參數

  與其他數據訪問 API 相比pureQuery 中的參數可以采用更多種類的類型例如一個聲明的 pureQuery bean 參數可以為 一些 SQL 語句參數占位符 提供運行時值對於 pureQuery 帶注釋的方法pureQuery bean 和 Java 集合類型都受支持請查看帶注釋的方法 語法圖以獲得可能聲明的參數類型的完整列表帶注釋方法的聲明的參數類型可以在很大程度上影響 SQL 語句的執行例如可以通過使用帶注釋的方法 @Update 中的某些參數類型發起批量更新對於批量更新需要使用一個集合參數多次執行一條 SQL 語句每次執行時使用不同的參數值

  帶注釋的方法的參數可以直接使用也可以賦給變量以利用 pureQuery 引擎的特定處理功能批量更新處理是 pureQuery 引擎底層自動優化代碼和改進開發的一個例子對數據 bean 參數的特殊 pureQuery 處理還可以節省開發時間和精力例如 @GeneratedKey pureQuery bean 注釋使 pureQuery 引擎可以用插入或更新操作後生成的數據庫值自動更新 bean 參數的字段

  Hook

  由於大多數代碼都是使用帶注釋的方法的風格生成的pureQuery 開發小組中有些人一開始有所顧慮Bob 解釋道 Hook 在執行生成的代碼期間為進行特殊處理提供了一種簡單的方法現在不需要手動編寫方法調用以便將每個應用程序調用圍繞一個帶注釋的接口方法而是采用另一種方法定義一個 Hook 以注冊到帶注釋的接口在進入和退出每個帶注釋的方法時pureQuery 運行時回調 Hook這提供了一種回調機制以便將生成的數據訪問代碼與特殊的處理關聯起來Hook 定義所需的 pre() 方法Hook 進行注冊後在進入一個帶注釋的方法時得到調用每個 Hook 還將定義一個 post() 方法當該 Hook 注冊後在從一個帶注釋的方法返回控制之前該方法會被立即調用

  Hook 方法為特殊的運行時回調處理提供上下文感知以防 pre() 和 post() 的用戶定義實現需要它這種感知是通過 pre() 和 post() 方法調用中的參數獲得的可以根據這些參數的值設計不同的特殊處理例如取決於調用 Hook 方法的接口方法的名稱提供給那個方法的運行時參數值或者該方法執行的 SQL 語句類型的不同處理也會有所不同此外還以 Data 參數的形式提供了 Hook 所注冊的 pureQuery 接口的一個句柄這些值都可以供 Hook 的實現者查看和修改此外返回值在被返回給調用者之前還可以供 post() 方法的實現者使用下面是 Bob 為了向 Silver Castles 小組進行演示而編寫的 Hook 處理代碼的一個例子

  清單 用於特殊處理的 Hook

   public static class TrackingHook implements Hook {

   public void pre(String methodName Data objectInstance
                    SqlStatementType sqlStatementType Object parameters)  {
      Systemoutprintln(methodName + **Customer data has been accessed**);
   }

   public void post(String methodName Data objectInstance
                    Object returnValue SqlStatementType sqlStatementType
                    Object parameters) {
     // do nothing
  }
}

  至此已經使用 Hook 定義了特殊的處理開發人員可以通過向進行實例化的接口注冊他們的 Hook 的一個實例以確保可以運行清單 展示如何注冊一個 Hook

  清單 注冊一個 Hook

  
Connection con = ;

// use the DataFactory to instantiate the interface and
// provide an instance of Hook to be registered with the instance
  
CustomerData cd = DataFactorygetData(CustomerDataclass con new TrackingHook());

// execute the SQL for getCustomers() and get the results
// the pre() and post() methods are automatically called
Iterator<Customer> cust = cdgetCustomers();

// the application now consumes the Iterator of Customer beans

  這是有關 Hook 的特殊處理的一個非常簡單的例子請參閱 pureQuery 文檔中的 Hook 示例以查看可以使用 Hook 實現的更復雜的類型示例

  針對多目標的開發

  Bob 向他的小組解釋了帶注釋的方法的最後一個特性使用 XML 配置文件 將 SQL 語句與應用程序的 Java 代碼實現完全分離這樣一來當將 Java 應用程序部署到一個要求不同 SQL 語句的目標數據庫時就可以避免重復編寫該 Java 應用程序例如如果小組想將同一個應用程序部署到一個遺留數據源上且該數據源使用稍有不同的模式那麼他們不需要重新編寫帶注釋的接口或 pureQuery bean

  清單 展示了用於初始模式的 SQL 語句

  清單 用於初始模式的 SQL 語句

   select CID NAME COUNTRY STREET CITY PROVINCE ZIP PHONE INFO
     from PDQ_SCCUSTOMER

  清單 展示了用於遺留模式的 SQL 語句

  清單 用於遺留模式的 SQL 語句

   select CUSTID NAME COUNTRY STREET CITY PROV ZIP PHONE INFO
     from PDQ_SCCUSTOMER

  注意在清單 CID 和 PROVINCE 列的名稱變成了 CUSTID 和 PROV這改變了用於發出查詢的 SQL 語句也改變了從結果到 Customer 數據 bean 的默認映射

  清單 展示了 customer pureQuery bean

  清單 Customer pureQuery bean

   package comibmdbpureQuery;

public class Customer  {

     // Class variables
     protected int cid;
     protected String name;
     protected String country;
     protected String street;
     protected String city;
     protected String province;
     protected String zip;
     protected String phone;
     protected String info;

  小組無需編寫新的帶注釋的接口或 Customer bean 類來支持遺留模式只需使用一個 XML 配置文件向生成器提供附加的輸入以支持遺留模式下面列出了 XML 配置文件的一個片段它展示了如何覆蓋一個 SQL 字符串和用戶定義 bean 類映射為了將應用程序部署到遺留系統上小組將初始的帶注釋的接口定義和下面的 XML 文件提供給生成器生成器產生正確的生成代碼從而部署到遺留數據庫上

  清單 生成替換代碼的 XML 配置文件

   <?xml version= encoding=UTF?>
<entitymappings xmlns=>

<namednativequery name= comibmdbpureQueryCustomerData#getCustomers()>
  <query><![CDATA[select CUSTID NAME COUNTRY STREET CITY PROV ZIP PHONE INFO
                     from PDQ_SCCUSTOMER]]>
  </query>
</namednativequery>

<entity class=com comibmdbpureQueryCustomer>
        <attributes>   
                    <basic name=cid>
                      <column name=CUSTID />
                    </basic>
                                   
                    <basic name=province>
                       <column name=PROV />
                    </basic>
                              
        </attributes>
        </entity>
</entity>
</entitymappings>

  要了解關於將 XML 配置文件提供給生成器以便為 pureQuery 接口提供備選 SQL 語句和/或對象映射的更多信息請參閱 pureQuery 在線文檔

  結束語

  本文概要地介紹了 pureQuery 帶注釋的方法編程風格以及開發小組選擇使用 pureQuery 帶注釋的方法進行編程的動機本文還列出了開發帶注釋的方法風格的應用程序所需的步驟另外也介紹了這種風格的部分特性

  如果您有興趣進一步了解如何開發 pureQuery 帶注釋的方法風格的應用程序請訪問本文正文和參考資料小節中提供的 pureQuery 在線文檔其他文章和相關教程的鏈接


From:http://tw.wingwit.com/Article/program/Java/JSP/201311/19786.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.