IBM® pureQuery 是一種高性能 Java™ 數據訪問平台,其目標主要是簡化數據訪問應用程序的開發和管理。它由工具、API 和運行時組成。pureQuery 引入了兩種編程風格,以幫助用戶通過簡單但是強大的 API 訪問數據庫。本文介紹其中的一種風格,即內聯方法編程風格,並討論如何使用它有效地查詢和更新數據庫。本文還探索使用內聯方法編程風格的一些優點和關鍵特性。
簡介
pureQuery 為 SQL 執行引入了兩種編程風格:內聯方法編程風格和帶注釋的方法編程風格。這些編程風格為存儲和檢索對象(例如 Java bean 和 map)提高了現成的支持,從而簡化了 Java 數據訪問開發。內聯編程風格還支持使用定制的用戶定義的結果處理。
帶注釋的方法風格提供一種基於注釋的數據訪問方法。在帶注釋的方法風格中,SQL/XQUERY 字符串是在一個 pureQuery 注釋(Annotation)中定義的。這些注釋被放在用戶定義接口中的方法聲明上。代碼生成器對接口進行預處理,生成每個帶注釋的方法的實現代碼。生成的實現代碼使用 pureQuery 運行時執行注釋中定義的 SQL 語句。要了解關於帶注釋的方法風格的更多信息,請參閱本系列的 第 1 部分 或 pureQuery 文檔。
pureQuery 內聯編程風格的目的是減少使用 JDBC 查詢或更新數據庫時常見的一些重復任務。內聯方法風格引入了一組定義良好的、有效的 API,它們比 JDBC 更簡單,更易於使用。在內聯風格中,可以在代碼中像 Java String 對象一樣 “內聯” 地創建 SQL/XQUERY 語句。這種動態生成的語句被作為 String 參數傳遞給 pureQuery Data 接口方法。內聯風格使用 JDBC 最佳實踐,並利用特定於數據庫的 API 來提高性能。內聯方法風格的一個例子是使用批量更新和改進的結果集處理。在帶注釋的方法風格中,SQL 必須在編譯時定義,而內聯方法則不同,它支持在運行時動態創建和執行 SQL 語句。在應用程序中,SQL 是 “內聯” 和可見的,因此更容易發現錯誤並做出更正。內聯風格還有一個可插入式定制結果處理,用於輕松地映射數據庫列。
表 1 中的代碼片段演示了內聯方法風格的簡單性和易用性。
表 1. JDBC 與 pureQuery 內聯風格之間的代碼比較
JDBC
try {
//SQL for insert
String sqlins="'insert into CUSTOMER ("
+ "NAME, COUNTRY, STREET, CITY, PROVINCE, ZIP,"
+ "PHONE,INFO)"
+ "values( ?, ?, ?, ?, ?, ?, ?, ?)";
//prepare the INSERT statement
PreparedStatement pstmt =
con.prepareStatement(sqlins );
// setup parameters
pstmt.setString (1, "custName");
pstmt.setString (2, "custCountry");
pstmt.setString (3, "custStreet");
pstmt.setString (4, "custCity");
pstmt.setString (5, "custProvince");
pstmt.setString (6, "custZip");
pstmt.setString (7, "custPhone");
pstmt.setString (8, "custInfo");
//execute the INSERT statement
pstmt.execute();
//close the prepared statement
pstmt.close();
// SQL for SELECT
String sqlSel = "select Name, Country, Street, "
+ "Province,Zip from CUSTOMER where Customer = ?";
//prepare the SELECT statement
pstmt = con.prepareStatement(sqlSel);
//set the Input parameter
pstmt.setString (1, "custCountry");
//execute SELECT statement
pstmt.execute();
//get the results and set values in Customer Bean
ResultSet result = pstmt.getResultSet ();
List<Customer> custList =
new ArrayList<Customer>();
while (result.next ()) {
Customer cust = new Customer();
cust.name = result.getString (1);
cust.country = result.getString (2);
cust.street = result.getString (3);
cust.province = result.getString (4);
cust.zip = result.getString (5);
custList.add (cust);
}
}
catch (SQLException e) {
e.pringStackTrace ();
}
pureQuery 內聯風格
//Get Instance of Data
Data data = DataFactory.getData(con);
// SQL for insert
String sqlins = "insert into CUSTOMER ("
+ "NAME,COUNTRY,STREET,CITY,PROVINCE,ZIP, "
+ "PHONE, INFO)"
+ "values( ?, ?, ?, ?, ?, ?, ?, ?)";
//execute the INSERT statement
data.update (sqlins, "custName",
"custCountry", "custStreet", "custCity",
"custProvince", "custZip", "custPhone", "custInfo");
// SQL for SELECT
String sqlSel = "select Name, Country, Street, "
+ "Province,Zip from CUSTOMER where Customer = ?";
//execute the Select and get the list of customer
List<Customer> customerList = data.queryList (sqlSel, Customer.
class , "custCountry");
本文內容包括:
詳盡描述需要使用內聯編程風格的代碼的各個方面
通過一個案例研究揭示內聯風格的特性
介紹內聯風格提供的查詢功能,包括 pureQuery 的默認映射支持和定制的查詢映射支持
介紹單個更新和批量更新支持,以及用於檢索自動生成的值的 API
介紹 pureQuery 的可插入式回調機制
開發內聯方法
下面是編寫內聯方法風格應用程序所需的不同對象和 API:
Data 接口
com.ibm.pdq.runtime.Data 接口定義了方便的 API,用戶可以用這些 API 執行數據庫中的操作。當使用內聯方法編程風格時,用戶可以調用 Data 接口中定義的方法,將 SQL 語句作為方法調用中的一個參數。Data 接口提供執行查詢、執行 SQL CALL 語句和返回輸出參數的方法。它還提供了訪問存儲過程創建的動態結果集的方法,以及作為單獨的操作或類型相同的批處理操作執行 SQL 數據操縱語言(DML)語句(例如更新、插入或刪除)的方法。很多 Data 接口的查詢方法是通用的,所以它們可以返回包括集合在內的不同類型的實例。
DataFactory 類
com.ibm.pdq.runtime.factory.DataFactory 類為構造 Data 接口的實現提供了途徑。創建 Data 接口的實現的一種方法是將一個 Connection 對象傳遞給 DataFactory.getData() 方法。
pureQuery bean
pureQuery bean 可用於表示關系數據,例如數據庫表、視圖、結果集等。雖然 pureQuery API 方法可以處理定義為非結構化類型的參數和返回值,但是使用 pureQuery bean 可以為用戶提供更好的從關系數據到 Java 對象的映射能力。 pureQuery 分析 bean 中聲明的屬性、方法和注釋,以決定如何在 bean 的屬性與 SQL 語句的輸入/輸出屬性之間進行映射。有關 pureQuery bean 的約定和需求的更多信息,可以在 pureQuery 文檔 中找到。
使用內聯方法的 Java 應用程序
在這種 Java 文件中,用戶可以創建 Data 接口的實例,並調用不同的查詢、更新或調用方法。
Silver Castle 示例
本節介紹一個示例,看看虛構的 Silver Castles 公司的數據訪問開發小組如何使用 pureQuery。本文使用這裡描述的背景信息展示針對每個 pureQuery 內聯特性的例子和用例。
Silver Castle 示例的背景信息
Silver Castles 是一家正在發展中的公司,銷售各種銀制品。這家公司正在開發一個新的基於 Web 的店面,並且已經決定使用 pureQuery 環境作為開發應用程序持久層的工具。開發小組對 pureQuery 工具環境有了深刻的理解後,他們開始深入研究 pureQuery 內聯編程風格的各個技術特性。
示例內聯方法風格編程
Silver Castle 開發小組定義了 Customer 表,如下所示:
清單 1. 數據庫中定義的 Customer 表
CREATE TABLE PDQ_SC.customer(
Cid INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (STARRT WITH 100, INCREMENT BY 1),
Name VARCHAR(128),
Country VARCHAR(128),
Street VARCHAR(128),
City VARCHAR(128),
Province VARCHAR(128),
Zip VARCHAR(128),
Phone VARCHAR(128),
Info VARCHAR(128),
CONSTRAINT CID_PK primary key(Cid));
用於這個 Customer 表的 pureQuery bean 可以使用 Data Studio tool 生成。這個 Customer bean 定義如下:
清單 2. Customer 類
public class Customer {
// Class variables
@Id
@GeneratedKey
public int cid;
public String name;
public String country;
public String street;
public String city;
public String province;
public String zip;
public String phone;
public String info;
public Customer(){}
public Customer(String name, String country, String street, String city, String province,
String zip, String phone, String info){
this.name = name;
this.country = country;
this.street = street;
this.city = city;
this.province = province;
this.zip = zip;
this.phone = phone;
this.info = info;
}
}
現在,Silver Castles 開發小組嘗試創建一個測試程序(清單 3),執行以下操作:
獲得一個到數據庫的連接
獲得 Data 接口實現的一個實例
刪除數據庫中的所有行
使用 pureQuery bean 作為輸入參數插入一行
查詢數據庫並在 pureQuery bean 的一個迭代器中檢索行
清單 3. 使用內聯方法風格操縱數據對象
package com.ibm.db2.demo;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Iterator;
import java.util.List;
import com.ibm.db2.pureQuery.Customer;
import com.ibm.pdq.runtime.Data;
import com.ibm.pdq.runtime.factory.DataFactory;
public class InlineTest
{
public static void main(String args[]) {
Connection con = null;
String sql = null;
String insertSql = null;
try {
// connection to the database
con = DriverManager.getConnection ();
// Get an instance to the implementation of a Data interface
Data data = DataFactory.getData (con);
//delete all rows from the table
data.update ("delete from PDQ_SC.customer");
//Insert using a pureQuery Bean
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
"Province, Zip, Phone)" +
"VALUES(:name,:country,:street,:city,:province,:zip,:phone)";
Customer addCustomer = new Customer("Customer2","US","BlackBerry Street",
"San Jose","Santa Clara","82652","408-273-4856",null);
int insertCount = data.update (insertSql,addCustomer );
System.out.println ("Rows Inserted " + insertCount );
sql = "select * from PDQ_SC.Customer where Country = ?";
//Query with Iterator using default handler
Iterator<Customer> iterator = data.queryIterator (sql, Customer.class, "US");
con.close ();
}
catch (Exception e) {
System.out.println ("Error encountered");
e.printStackTrace ();
}
}
public static Connection getConnection ()
{
Connection connection = null;
try {
Class.forName ("com.ibm.db2.jcc.DB2Driver").newInstance ();
java.util.Properties info = new java.util.Properties ();
info.put ("retrieveMessagesFromServerOnGetMessage", "true");
info.put ("user", "USER");
info.put ("password", "PASSWORD");
String url = "jdbc:db2://atom.blue.test.com:298/SAMPLE:deferPrepares=false;";
connection = DriverManager.getConnection (url, info);
}
catch (Exception e) {
e.printStackTrace ();
}
return connection;
}
}
創建 Data 對象的一個實例
要創建 com.ibm.pdq.runtime. Data 的一個實例,需要一個到數據庫的連接,其形式應該為 java.sql.Connection 對象或 javax.sql.DataSource 對象。建立好連接後,用戶可以調用 com.ibm.pdq.runtime.factory.DataFactory 中的 getData() 方法創建 Data 接口的一個實例。除了執行 SQL 語句的方法以外,Data 接口還支持 close()、commit()、rollback() 和 setAutoCommit() JDBC 方法。
在 清單 3 中,Silver Castle 小組使用 getConnection() 方法創建一個數據庫連接。該方法使用 Driver Manager API,通過傳遞一個數據庫連接 URL String 來創建這個連接。然後,該連接被傳遞給 DataFactory.getData() 方法,以獲得 Data 接口的實例。
輸入參數選項
Silver Castle 開發人員可能希望使用 pureQuery 提供的參數占位符或主機變量風格。他們可以根據偏好選擇內聯方法的輸入參數的數量或類型。傳入方法調用的參數要與 SQL 中的參數匹配。pureQuery 根據 參數占位符規則 確定 SQL/XQUERY 中聲明的參數與傳遞給內聯方法的參數之間的映射。在最簡單的形式中,兩組參數之間有一對一的映射。pureQuery 還可以帶各種類型的參數,例如 pureQuery Bean 或 java.util.Map。
查詢數據庫中的對象
內聯方法風格提供了一些便利方法,並提供對將數據庫結果映射到 map 和 pureQuery bean 的現成支持。Data 接口的重載方法 queryArray()、queryIterator() 和 queryList() 可用於以 Array、Iterator 或 List 對象的形式返回查詢的結果集。
查詢方法可以以原語類型、bean、集合等類型返回結果,包括:
java.sql.ResultSet
JDBC 直接支持基本包裝器類型或簡單的 Object 類型(不包括用戶定義的類型)
java.util.Map 對象,其中列名成為 String 鍵,列值成為 Object 值
組成 Array、Collection 或 Iterator 的 java.util.Map 對象
單個的 pureQuery bean,用戶可以將查詢的結果存儲在一個 pureQuery Bean 中(@Column 注釋提供將 select 列表中的列與 pureQuery bean 各個屬性相關聯所需的信息;有關 pureQuery 注釋的更多信息可以在 pureQuery 文檔 中找到)。
組成 Array、Collection 或 Iterator 的 pureQuery bean,返回 bean 的類作為參數傳遞
決定了目標數據類型後,用戶需要考慮是否使用定制的處理程序將從數據源選擇的信息轉換成目標數據。pureQuery bean 的實例可以用 pureQuery 的從 SELECT 語句的 select 列表到目標 Bean 類的默認映射來創建,也可以使用一個用戶定義的處理程序創建。
查詢 Silver Castle Customer 表
Silver Castle 開發人員想通知澳大利亞(Australia)的所有客戶即將舉辦一次鹽和胡椒攪拌器的特價活動。用於打印所有宣傳冊的通用打印實用方法以一個 java.util.List 作為輸入。開發人員查詢 Customer 表,選擇居住在 Australia 的所有客戶,並將返回的行放在一個 List 中。他們可以使用 queryList() API,並以國家名作為輸入參數。然後,返回的列表(在下面的例子中是 customerList)被傳遞到打印實用程序,以便為列表中適當的客戶打印宣傳冊。
清單 4. 查詢 Customer 表
sql = "select * from PDQ_SC.Customer where Country = ?";
//Query with List using default handler
List<Customer> customerList = data.queryList (sql, Customer.class, "Australia");
用戶定義的定制結果集映射
RowHandler 和 ResultHandler 接口使用戶可以提供定制的用戶定義映射。可以告訴 pureQuery 如何使用 RowHandler 或 ResultHandler 接口中的 handle() 方法將結果集中的列映射到不同的 Java 對象。Row Handlers 和 Result Handlers 為開發人員帶來更大的靈活性和代碼重用的潛力,因為他們可以使用 ResultSet 的 ResultSetMetaData 來處理 select 列表中的變化。這可以用於省略一些屬性,或者指定不需要的屬性。
在某些情況下,應用程序開發人員可能需要對整個查詢結果進行某種形式的串行化。例如,惟一可以對查詢結果做的處理是串行化到 JSON 或 XML 中,或者將數據發送到另一個(或相同的)數據源。用戶可以使用 ResultHandler 來執行這樣的定制操作。
映射結果集中的一行
RowHandler 接口用於將結果集的一行映射到一個對象。 RowHandler 接口中惟一的方法是 handle()。這是一個泛型方法,其輸入為一個 ResultSet 對象,可能還有 <T> 類的一個實例,它或者產生一個新的 <T> 類的 Java 對象,或者更新給定的 <T> 實例。如果 ResultSet 對象為空,或者讀完 ResultSet 對象的最後一行,則不調用 handle() 方法。當 handle() 方法被調用時,傳遞給該方法的 ResultSet 對象被定位到要處理的行上。當 pureQuery 自動執行這個動作時,handle() 方法不能對輸入 ResultSet 對象調用 next() 方法。
將結果集映射到對象
ResultHandler 接口用於將整個結果集映射到一個對象。用戶可以使用 ResultHandler 接口中的 handle() 方法將查詢結果轉換成另一個對象,例如 XML,後者可以傳遞給另一個以 XML 作為輸入的應用程序。
更新數據庫中的對象
Data 接口的 update() 方法可用於執行對數據庫對象的單個更新,而 updateMany() 方法則可用於基於單個 SQL 語句的批量更新。受支持的方法有 INSERT、DELETE 和 UPDATE 操作。
單個更新
Data 接口中的 update() 方法可用於單個操作,它返回一個更新計數。清單 5 是在應用程序中調用重載方法 update() 的一個例子。
清單 5. 調用重載方法 update() 的應用程序
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
"Province, Zip, Phone) VALUES (:name, :country, :street, " +
":city, :province,:zip,:phone)";
//Create an instance of Customer Bean with the values to be inserted
Customer addCustomer =
new Customer("Customer2","US","BlackBerry Street","San Jose",
"Santa Clara","82652","408-273-4856", null);
//Insert using a Bean
int updateCount = data.update (insertSql, addCustomer);
批量更新
在 Data 接口中,updateMany() 方法表明一條語句要運行多次。updateMany() 方法允許傳遞一個集合的數據來進行遍歷。
和在 JDBC 中一樣,返回的 int 數組表明 SQL 語句的每次運行是成功還是失敗(以及相關的更新計數)。這包括 JDBC 的更新計數、 Statement.EXECUTE_FAILED 和 SUCCESS_NO_INFO。如果出現失敗,則拋出 com.ibm.pdq.runtime.exception.UpdateManyException 異常。這個運行時異常包含 JDBC 在 java.sql.BatchUpdateException 中報告的信息。
更新 Silver Castle Customer 表
每兩個月,客戶就可能與 Silver Castle 管理小組聯系,以更新地址或電話號碼。Silver Castle 開發人員可以使用單個更新 API 以新的信息更新這個表。清單 6 展示了這種 API 的使用。
清單 6. 用於更新表的單個更新 API
//Update the Street name for Customer
String updateSql = "UPDATE PDQ_SC.customer SET Street= 'Townsend' WHERE name= ?";
int updateCount = data.update (updateSql,"Customer3");
System.out.println ("Rows Updated " + updateCount);
Silver Castle 小組還有一個網站,新客戶可以登錄到這個網站上,讓 Silver Castle 將目錄郵遞給他們。每個月都會運行一個實用程序來更新 Customer 數據庫,以添加這些新客戶。為此,開發人員可以創建一個任務,批量處理所有請求並使用一個內聯方法將它們插入到數據庫中。在這種情況下,他們可以使用批量更新 API,以高效地更新數據庫。清單 7 展示了批量更新 API。
清單 7. 批量更新 API
//Example Using UpdateMany
Customer addFirstCustomer =
new Customer("Customer3","Costa Rica","Main Street","Arenal",
"La Fortuna","90291","506-375-0273",null);
Customer addSecondCustomer =
new Customer("Customer4","Puerto Rico","Church Street",
"Puerto Nuevo","San Juan","38364","293-484-8244",null);
ArrayList<Customer> customerList = new ArrayList<Customer>();
customerList.add (addFirstCustomer);
customerList.add (addSecondCustomer);
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
"Province, Zip, Phone) VALUES (:name, :country, :street, " +
":city, :province,:zip,:phone)";
int[] updateCount = data.updateMany( sql, customerList);
if (updateCount != null)
System.out.println ("Rows Inserted:” + updateCount.length);
檢索自動生成的值
update() 方法的重載使用戶可以有選擇地請求與自動生成的列相關的信息。Silver Castle 開發人員可以用很多方法根據提供給更新方法的輸入獲取數據庫生成的值。下面展示了一個例子,在這個例子中,Silver Castle 開發人員使用不同的方法編寫應用程序,以獲得插入後數據庫生成的值。
使用 pureQuery bean 自動生成的值
在這個例子中,插入的輸入是一個 pureQuery bean。Customer 對象是在一個 @GeneratedKey 注釋中定義的,列 CID 被定義為標識列,它總是生成一個整數。在 update() 方法調用返回控制之前,CID 列中的值被傳遞到 CID 屬性中。自動生成的值是在 customer 對象的 CID 屬性中設置的。
清單 8. 獲得 Customer bean 的 CID 屬性中自動生成的值
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, " +
"Province, Zip, Phone) VALUES (:name, :country, :street, " +
":city, :province,:zip,:phone)";
//Create an instance of Customer Bean with the values to be inserted
Customer customer =
new Customer("Customer2","US","BlackBerry Street","San Jose",
"Santa Clara","82652","408-273-4856", null);
//Insert using a Bean
int updateCount = data.update (insertSql, customer);
System.out.println ("Generated Key Value:" + customer.cid);
不使用 pureQuery Bean 自動生成的值
The Silver Castle developer can pass values without a pureQuery bean and still retrieve auto-generated values by using the following version of the update() method:
<T> T update(java.lang.String sql, Class<T> returnClass,
String[] columnNames, Object... parameters)
取決於指定的返回類型,該方法返回一個或多個生成的值。返回類型為 Class<T> 的值必須是以下兩者之一:
Object[].class
一個可直接從 JDBC 指定的簡單的類,例如 Integer.class 或 String.class
當返回類型為一個簡單的可直接指定的 JDBC 類時,會返回給定類型的一個生成的值。而更新計數不會返回。下面展示了 Silver Castle 開發人員如何將自動生成的值放入到一個簡單的類(例如 int.class)中。
清單 9. 將自動生成的值放入一個簡單的類中
Object[] customerArray = new Object[7];
customerArray[0] = "CustomerForGenKey";
customerArray[1] = "US";
customerArray[2] = "Bixby Street";
customerArray[3] = "San Martin";
customerArray[4] = "Santa Clara";
customerArray[5] = "62826";
customerArray[6] = "408-272-6565";
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street," +
"City, Province, Zip, Phone) VALUES(?,?,?,?,?,?,?)";
String[] colunmName = new String[] { "cid" };
int i = data.update (insertSql, int.class, colunmName, customerArray);
System.out.println ("AutoGenerated Keys as Int " + i + "\n");
當返回類型為 Object[].class 時,數組的前 n 個元素是從 columnName 參數中的列生成的 n 個值。數組中的最後一個元素是更新計數。下面展示了 Silver Castle 開發人員如何使用一個 Object[] 獲得生成的鍵值。自動生成的值在 Object[0] 中返回,更新計數在 Object[1] 中返回,如清單 10 所示。
清單 10. 將自動生成的值放在一個 Object[ ] 中
Object[] customerArray = new Object[7];
customerArray[0] = "CustomerForGenKey";
customerArray[1] = "US";
customerArray[2] = "Barnaby Street";
customerArray[3] = "Gilroy";
customerArray[4] = "Santa Clara";
customerArray[5] = "62823";
customerArray[6] = "408-273-6568";
insertSql = "INSERT INTO PDQ_SC.customer (Name, Country, Street," +
" City, Province, Zip, Phone) VALUES(?,?,?,?,?,?,?)";
String[] colunmName = new String[] { "cid" };
Object[] output = data.update (insertSql, Object[].class,
colunmName, customerArray);
使用 Hook 接口的可插入式回調機制
com.ibm.pdq.runtime.Hook 接口可用於創建在內聯方法之前或之後運行的方法。假設 Silver Castle 開發人員知道他們的產品不能發送給某些國家的客戶。對於這裡的例子,我們可以假設有發貨限制的這些國家是 Costa Rica 和 Australia。Hook 接口使開發人員只需定義一次這樣的檢查,而不必在每次更新 Customer 表時在多個位置添加代碼來檢查客戶的國家。
當 Data 實例創建時,必須將 Hook 注冊到 Data 實例。如果內聯方法使用的 Data 對象注冊了 Hook,那麼當應用程序調用 Data 接口的一個方法時,會出現以下步驟:
在 Data 接口的方法做任何事情之前,先調用注冊的 Hook 的 pre() 方法。
被調用方法執行它的工作。
當被調用方法完成所有工作之後,調用注冊的 Hook 的 post () 方法。
定義內聯方法的 Data 接口包含很多 Connection 對象上的 JDBC 方法,例如 close ()、commit ()、rollback ()、setAutoCommit () 和 getAutoCommit ()。注冊的 Hook 的 pre () 和 post () 方法不會包裝這些方法。
pre () 和 post () 方法需要使用以下參數來定義:
String methodName: pureQuery 將方法的簽名傳遞給 pre () 方法
Data dataInstance: pureQuery 傳遞實現 Data 接口的對象
SqlStatementType statementType: pureQuery 傳遞 SQL 語句的類型(例如 SELECT、UPDATE、INSERT)
Object... parameters: pureQuery 傳遞傳給內聯方法的參數
Object returnValue: 將調用值返回給內聯方法
下面的例子演示了 Hook 接口的使用。Silver Castle 應用程序開發人員在應用程序的一個 HookCall 類中定義 pre() 和 post() 方法。pre() 方法檢查輸入參數,即客戶的國家,看它是否有效,並防止將無效的行插入到數據庫中。方法調用的輸出可以使用 post() 方法檢查。
清單 11. Hook 接口的使用
public static class HookCall implements Hook
{
public void pre (String methodName, Data objectInstance,
SqlStatementType statementType, Object... parameters)
{
String country = ((Customer)parameters[0]).country;
If (!statementType.equalsIgnoreCase ("update") ||
!statementType.equalsIgnoreCase("insert")) return;
if (!(country.equals ("Australia") || country.equals ("Costa Rica")) )
throw new DataRuntimeException
("This Country " + country + " is not part of our customer base");
}
public void post (String methodName, Data objectInstance,
Object retValue, SqlStatementType statementType,
Object... parameters)
{
//Do nothing
}
}
應用程序可以像下面清單 12 中那樣注冊 Hook。當 pre() 方法被調用時,它會驗證用於 Customer bean 的 country 屬性的輸入值。
清單 12. 注冊 hook
Connection con = DriverManager.getConnection(...);
HookCall hookCall = new HookCall ();
Data db = DataFactory.getData(con, hookCall);
sql = "INSERT INTO PDQ_SC.customer (Name, Country, Street, City, Province, Zip, Phone)"
+ "VALUES(:name,:country,:street,:city,:province,:zip,:phone)";
Customer addCustomer2 = new Customer ("Customer2", "Costa Rica", "BlackBerry Street",
"San Jose", "Santa Clara", "82652","408-273-4856", null);
int insertCount = db.update (sql, addCustomer2);
結束語
本文對 pureQuery 內聯方法編程風格作了一個概述。文中提供了一些示例,以演示開發小組使用內聯方法開發 pureQuery 應用程序的動機。本文還列出了開發內聯方法風格應用程序所需的基本步驟。另外,本文還介紹了這種風格的一些強大的特性,這些特性可能促使人們使用內聯方法編程風格編寫代碼。
如果您有興趣了解更多關於開發 pureQuery 內聯風格應用程序的知識,請訪問本文正文和參考資料小節中提供的 pureQuery 在線文檔、其他文章和有幫助的教程的鏈接。