データベース コントロール メソッドから複数の行を返す
このトピックでは、データベース コントロールに追加でき、データベースから複数の行を返すメソッドについて説明します。
データベース コントロールの詳細については、データベース コントロール : Web サービスからデータベースを使用するを参照してください。
データベース コントロールの作成方法については、新しいデータベース コントロールを作成するを参照してください。
一部のデータベース処理は複数の行から 1 つまたは複数のカラムを返します。そうした処理の例としては、複数行から 1 つまたは複数のカラムを返す SELECT 処理があります。
データベース処理から複数の行を返すには複数の方法があります。複数の行を返す手順は、すでに説明した単一の行を返す手順と似ています。データベース コントロール メソッドから単一の行を返すを参照してください。
まず、配列と java.util.Iterator のどちらを返すかを選択します。
コントロールのユーザにとっては、イテレータの使い方を理解する必要がないので、オブジェクトの配列の方が便利です。ただし、配列を返す場合、1 つのデータベース処理のみが実行されるので、結果セットをメモリに格納する必要があります。大きな結果セットの場合、問題があります。返される配列のサイズを制限することはできますが、残りの結果セットを取得する方法をユーザに提供することはできません。
オブジェクトの配列を返す方法については、オブジェクトの配列を返すを参照してください。
イテレータを返すと、コントロールのユーザの操作は複雑になりますが、大きな結果セットをより効率的に処理できます。イテレータは、イテレータの next() メソッドを使用して一度に 1 要素(行)にアクセスするので、すべてのレコードが処理されるまで、リクエストを透過的に繰り返します。イテレータを使用すると、配列を使用した場合と異なり、メモリが不足することはありません。
java.util.Iterator を返す方法については、イテレータを返すを参照してください。
最後に、データベース コントロール メソッドから java.sql.ResultSet を返すかどうかを選択できます。このインタフェースにより、コントロールのクライアントはデータベース処理の結果にアクセスできますが、java.sql パッケージの知識が必要となります。
java.sql.ResultSet を返す方法については、ResultSet を返すを参照してください。
オブジェクトの配列を返す場合、返したいオブジェクトの配列としてメソッドの戻り値の型を宣言します。型は、任意に定義する型または java.util.Hashmap です。
以下の節では、それぞれの方法の例を示します。
宣言した型を持つオブジェクトの配列を返す方法を次の例で示します。このケースでは、Customer オブジェクトの配列が返されます。
public static class Customer { public int custid; public String name; }
/** * @sql statement="SELECT custid,name FROM customer WHERE custage<19" * array-max-length=100 */ Customer [] findAllMinorCustomers()
この例は、custage フィールドに 19 より小さい値を持つすべての行を返します。
オブジェクトの配列を返す場合、メソッドの戻り値の型として宣言するクラスは、オブジェクトを返すの条件を満たしていなければなりません。
クエリによって行が返されなかった場合、データベース コントロール メソッドの戻り値はゼロ長の配列となります。
データベース コントロール メソッドによって配列を返す場合、@jws:sql タグには、array-max-length 属性を指定することができます。この属性によって、クエリがあいまいなために結果セットのサイズが非常に大きくなるということはなくなります。array-max-length を指定した場合、そのサイズを超える行数はメソッドによって返されません。
array-max-length のデフォルト値は 1024 です。
array-max-length 属性には、特殊な値 all を指定できます。この値は、クエリの条件を満たすすべての行を返すことを指示します。ただし、クエリが非常にあいまいな場合、使用可能なメモリ量がなくなることがあります。メモリの大量使用を防ぐには、イテレータを返すで説明するように、イテレータを返します。
HashMap の配列を返す方法は、前の節で説明したユーザ定義のオブジェクトを返す場合と似ています。
HashMap の配列を返す方法を次の例で示します。
public static class Customer { public int custid; public String name; public Customer() {}; }
/** * @sql statement="SELECT custid,name FROM customer WHERE custage<19" * array-max-length=100 */ java.util.HashMap [] findAllMinorCustomersHash()
返される HashMap の配列には返される各行の要素が含まれ、配列の各要素には結果内の各カラムのエントリが含まれます。各エントリのキーは対応するカラムの名前です。HashMap.keySet() で返されるキー名に大文字が使用されるかどうかはデータベース ドライバによって異なるので、HashMap のメソッドを使用してアクセスする場合、キーの大文字/小文字は区別されません。値は、データベース カラムの JDBC のデフォルト型のオブジェクトです。
クエリによって行が返されなかった場合、データベース コントロール メソッドの戻り値はゼロ長の配列となります。
Java と JDBC(データベース)間の各型のマッピングについては、データベース コントロールでデータベース フィールドの型を Java の型にマップするを参照してください。
呼び出し側の Web サービス(JWS ファイル)で返されたレコードの名前フィールドにアクセスするには、次のコードを使用します。
/** * @jws:control */ private CustomerDBControl custDB;
int custID = <some customer ID> java.util.HashMap [] hashArr; String name;
hashArr = custDB.findAllMinorCustomersHash(); for(i=0; i<hashArr.length; i++) { name = (String)hashArr[i].get("NAME"); // say hello to the all of the minors
System.out.println(“Hello, “ + name + “!”); }
イテレータを返すには、メソッドの戻り値の型を java.util.Iterator として宣言します。次に、iterator-element-type 属性を @jws:sql タグに追加して、イテレータが含む基底の型を示します。指定する型は、任意に定義する型または java.util.Hashmap です。以下の節では、それぞれの手法の例を示します。
注意 :返されるイテレータは、イテレータが返される JWS メソッド呼び出しの有効期間中のみ有効であることを保証されます。データベース コントロール メソッドから返されるイテレータを Web サービスのクラスの静的メンバーとして保存したり、別の方法で永続化したイテレータを後続のメソッド呼び出しで再利用しようとしたりしてはなりません。
ユーザ定義の型をカプセル化するイテレータを返すには、@jws:sql タグの iterator-element-type 属性の値としてクラス名を指定します。
public static class Customer { public int custid; public String name; public Customer() {}; }
/** * @sql statement="SELECT custid,name FROM customer" * iterator-element-type="Customer" */ java.util.Iterator getAllCustomersIterator()
iterator-element-type 属性で指定したクラスは、オブジェクトを返すで説明した条件を満たさなければなりません。
呼び出し側の Web サービス(JWS ファイル)で返されたレコードにアクセスするには、次のコードを使用します。
CustomerDBControl.Customer cust;
java.util.Iterator iter = null;
iter = custDB.getAllCustomersIterator();
while (iter.hasNext()) { cust = (CustomerDBControl.Customer)iter.next(); // say hello to every customer
System.out.println(“hello, “ + cust.name + “!”); }
HashMap をカプセル化するイテレータを返すには、@jws:sql タグの iterator-element-type 属性の値として java.util.HashMap を指定します。
public static class Customer { public int custid; public String name; public Customer() {}; }
/** * @sql statement="SELECT custid,name FROM customer" * iterator-element-type="java.util.HashMap" */ java.util.Iterator getAllCustomersIterator()
呼び出し側の Web サービス(JWS ファイル)で返されたレコードにアクセスするには、次のコードを使用します。
java.util.HashMap custHash; java.util.Iterator iter = null;
int customerID;
String customerName;
iter = custDB.getAllCustomersIterator();
while (iter.hasNext()) { custHash = (java.util.HashMap)iter.next(); customerID = (int)custHash.get("CUSTID");
customerName = (String)custHash.get("NAME"); }
HashMap には、クエリによって返された各データベース カラムのエントリが含まれます。各エントリのキーは対応するカラムの名前(すべて大文字)です。値は、データベース カラムの JDBC のデフォルト型のオブジェクトです。
Java と JDBC(データベース)間の各型のマッピングについては、データベース コントロールでデータベース フィールドの型を Java の型にマップするを参照してください。
クエリによって返される java.sql.ResultSet にアクセスすることができます。これは高度な用法です。データベース コントロールは、java.sql パッケージのクラスに関する知識がなくとも、ユーザがさまざまな方法でデータベースからデータを取得できるようにするためのものです。
ResultSet を返すには、メソッドの戻り値の型を java.sql.ResultSet として宣言します。コントロールのクライアントでは、ResultSet に直接アクセスして、データベース処理の結果を操作できます。
次の例で ResultSet を返す方法を示します。
/** * @jws:sql statement="SELECT * FROM customer" */ public java.sql.ResultSet findAllCustomersResultSet();
呼び出し側の Web サービス(JWS ファイル)で返された ResultSet にアクセスするには、次のコードを使用します。
java.sql.ResultSet resultSet; String thisCustomerName; resultSet = custDB.findAllCustomersResultSet(); while (resultSet.next()) { thisCustomerName = new String(resultSet.getString("name")); }
この例では、データベース処理で返される行に name というカラムが含まれているものとします。