不定期ユーザ向けの JDBC
JDBC では経験豊富な Java データベース開発者向けに概要を説明する必要はありませんが、使用頻度の低い小型のユーティリティ・アプリケーションでのみ Java を使用する場合であっても、この説明は非常に役立つ可能性があります。この章は JDBC の簡単な概要で、データベースにクエリを実行して結果を操作する Java コードの例を提供します。
簡単な JDBC アプリケーション
このセクションでは、最も一般的な JDBC クラスの一部の使用法を例示する非常に簡単な JDBC アプリケーションについて説明します。
-
IRISDataSource オブジェクトは、JDBC アプリケーションを InterSystems IRIS データベースにリンクする Connection オブジェクトの作成に使用されます。
-
Connection オブジェクトは、ダイナミック SQL クエリを実行可能な PreparedStatement オブジェクトの作成に使用されます。
-
PreparedStatement クエリは、要求された行を含む ResultSet オブジェクトを返します。
-
ResultSet オブジェクトには、特定の行に移動し、その行の特定の列の読み取りまたは更新を行うために使用することができるメソッドがあります。
これらのクラスについては、すべてこの章の後で詳しく説明します。
SimpleJDBC アプリケーション
最初に、JDBC パッケージをインポートし、try ブロックを開きます。
import java.sql.*;
import javax.sql.*;
import com.intersystems.jdbc.*;
public class SimpleJDBC{
public static void main() {
try {
// Use IRISDataSource to open a connection
Class.forName ("com.intersystems.jdbc.IRISDriver").newInstance();
IRISDataSource ds = new IRISDataSource();
ds.setURL("jdbc:IRIS://127.0.0.1:1972/User");
Connection dbconn = ds.getConnection("_SYSTEM","SYS");
// Execute a query and get a scrollable, updatable result set.
String sql="Select Name from Demo.Person Order By Name";
int scroll=ResultSet.TYPE_SCROLL_SENSITIVE;
int update=ResultSet.CONCUR_UPDATABLE;
PreparedStatement pstmt = dbconn.prepareStatement(sql,scroll,update);
java.sql.ResultSet rs = pstmt.executeQuery();
// Move to the first row of the result set and change the name.
rs.first();
System.out.println("\n Old name = " + rs.getString("Name"));
rs.updateString("Name", "Bill. Buffalo");
rs.updateRow();
System.out.println("\n New name = " + rs.getString("Name") + "\n");
// Close objects and catch any exceptions.
pstmt.close();
rs.close();
dbconn.close();
} catch (Exception ex) {
System.out.println("SimpleJDBC caught exception: "
+ ex.getClass().getName() + ": " + ex.getMessage());
}
} // end main()
} // end class SimpleJDBC
Note:
この章の残りの部分では、アプリケーション全体ではなくコード断片として例を表します。これらの例は、基本機能をできる限り簡単かつ明確に示しており、すぐれたコーディング方法の例示を目的としているわけではありません。接続が既に開かれていて、コード断片すべてが適切な try/catch 文の内側にあることを前提とします。
SQL 言語の設定
既定では、JDBC は InterSystems IRIS SQL 言語を使用します。以下の方法で、Transact SQL (TSQL) 言語をサポートするように言語を変更できます。
connection.setSQLDialect(int);
または
statement.setSQLDialect(int);
利用可能な int オプションは、0 = InterSystems IRIS SQL (既定)、1 = MSSQL、2 = Sybase です。
ドライバのプロパティで言語を定義することもできます。
言語が 0 より大きい場合、JDBC を介して準備または実行される SQL 文は、サーバ上で若干異なる方法で処理されます。文は指定した言語を使用して処理されてから、InterSystems IRIS SQL または ObjectScript 文に変換されます。
クエリの使用法
sql.java パッケージでは、データベースにクエリを実行して ResultSet を返す PreparedStatement クラスと CallableStatement クラスが提供されています。どちらのクラスも、Connection メソッドの呼び出しによってインスタンス化されます。以下のセクションでは、これら 3 つのクラスの使用方法を説明します。
作成済み文の実行
以下のクエリは、作成済み文を使用して、"M" ~ "Z" で始まる名前の会社を担当する “A” ~ "E" で始まる名前の従業員すべてのリストを返します。
Select ID, Name, Company->Name from Demo.Employee
Where Name < ? and Company->Name > ?
Order By Company->Name
Note:
この文は、暗黙結合構文 (–> 演算子) を使用しています。この構文は、Demo.Employee が参照する Company クラスにアクセスする簡単な方法を提供します。
作成済み文を実装するには、以下の手順に従います。
CallableStatement によるストアド・プロシージャの実行
以下のコードは、ByName (Demo.Person に格納されている InterSystems IRIS ストアド・プロシージャ) を実行します。
複数の結果セットを返す
InterSystems IRIS では、複数の結果セットを返すストアド・プロシージャを定義できます。InterSystems JDBC ドライバは、このようなストアド・プロシージャの実行をサポートしています。次に、2 つの結果セットを返す InterSystems IRIS ストアド・プロシージャの例を示します (2 つのクエリ結果の列構造は異なっています)。
/// This class method produces two result sets.
ClassMethod DRS(st) [ ReturnResultsets, SqlProc ]
{
$$$ResultSet("select Name from Demo.Person where Name %STARTSWITH :st")
$$$ResultSet("select Name, DOB from Demo.Person where Name %STARTSWITH :st")
Quit
}
$$$ResultSet は、SQL 文 (文字リテラルとして指定) を作成して実行し結果セットを返す事前定義 InterSystems マクロです。
以下のコードは、このストアド・プロシージャを実行し、返された結果セット両方の繰り返し処理を行います。
-
java.sql.CallableStatement オブジェクトを作成し、これをストアド・プロシージャの名前を使用して初期化します。クエリ・パラメータを設定し、execute を使用して、クエリを実行します。
CallableStatement cs = dbconnection.prepareCall("call Demo.Person_DRS(?)");
cs.setString(1,"A");
boolean success=cs.execute();
-
データを表示する結果セットのペアに繰り返し処理を行います。getResultSet が現在の結果セットを取得したら、getMoreResults は、その結果セットを閉じて、CallableStatement オブジェクトの次の結果セットへ移動します。
if(success) do{
java.sql.ResultSet rs = cs.getResultSet();
ResultSetMetaData rsmd = rs.getMetaData();
for (int j=1; j<rsmd.getColumnCount() + 1; j++)
System.out.print(rsmd.getColumnName(j)+ "\t\t");
System.out.println();
int colnum = rsmd.getColumnCount();
while (rs.next()) {
for (int i=1; i<=colnum; i++)
System.out.print(rs.getString(i) + " \t ");
System.out.println();
}
System.out.println();
} while (cs.getMoreResults());
データの挿入および更新
JDBC を使用して InterSystems IRIS データを挿入および更新するには、以下のような方法があります。
データの挿入および生成されるキーの取得
以下のコードは、新しい行を Demo.Person に挿入し、生成される ID キーを取得します。
-
PreparedStatement オブジェクトを作成し、これを SQL 文字列を使用して初期化し、生成されるキーが返されるように指定します。
String sqlIn="INSERT INTO Demo.Person (Name,SSN,DOB) " + "VALUES(?,?,?)";
int keys=Statement.RETURN_GENERATED_KEYS;
PreparedStatement pstmt = dbconnection.prepareStatement(sqlIn, keys);
-
クエリ・パラメータの値を設定し、更新を実行します。
String SSN = Demo.util.generateSSN(); // generate a random SSN
java.sql.Date DOB = java.sql.Date.valueOf("1984-02-01");
pstmt.setString(1,"Smith,John"); // Name
pstmt.setString(2,SSN); // Social Security Number
pstmt.setDate(3,DOB); // Date of Birth
pstmt.executeUpdate();
-
新しい行を挿入するたびに、システムは、その行のオブジェクト ID を自動的に生成します。生成される ID キーは、結果セットに取得され、SSN と共に表示されます。
java.sql.ResultSet rsKeys = pstmt.getGeneratedKeys();
rsKeys.next();
String newID=rsKeys.getString(1);
System.out.println("new ID for SSN " + SSN + " is " + newID);
このコードは ID が rsKeys で生成される最初で唯一のキーであることを想定していますが、実際にはこの想定が常に安全であるとは限りません。
-
ID で新しい行を取得し、これを表示します (Age は DOB に基づいて計算される値です)。
String sqlOut="SELECT IName,Age,SSN FROM Demo.Person WHERE ID="+newID;
pstmt = dbconnection.prepareStatement(sqlOut);
java.sql.ResultSet rsPerson = pstmt.executeQuery();
int colnum = rsPerson.getMetaData().getColumnCount();
rsPerson.next();
for (int i=1; i<=colnum; i++)
System.out.print(rsPerson.getString(i) + " ");
System.out.println();
トランザクションの使用法
InterSystems JDBC ドライバは、標準の JDBC トランザクション・モデルをサポートしています。
-
SQL 文をトランザクションにグループ化するには、最初に次のように setAutoCommit() を使用して、自動コミット・モードを無効化する必要があります。
dbconnection.setAutoCommit(false);
-
commit() の最後の実行またはロールバック以降に実行されたすべての SQL 文をデータベースに対してコミットするには、commit() を使用します。
pstmt1.execute();
pstmt2.execute();
pstmt3.execute();
dbconnection.commit();
-
トランザクション内のすべてのトランザクションをロールバックするには、rollback() を使用します。ここで、SQLException がトランザクションで任意の SQL 文によってスローされる場合、rollback() が呼び出されます。
catch(SQLException ex) {
if (dbconnection != null) {
try {
dbconnection.rollback();
} catch (SQLException excep){
// (handle exception)
}
}
}
次に、この例で使用する java.sql.Connection メソッドの概要を説明します。
-
setAutoCommit()
既定では、Connection オブジェクトは自動コミット・モードになっています。このモードでは、SQL 文は実行されるとすぐにコミットされます。複数の SQL 文を 1 つのトランザクションにグループ化するには、最初に setAutoCommit(false) を使用して Connection オブジェクトの自動コミット・モードを終了します。setAutoCommit(true) を使用して、Connection オブジェクトを自動コミット・モードに再設定します。
-
commit()
commit() を実行すると、commit() または rollback() の最後の実行以降に実行されたすべての SQL 文がコミットされます。最初に自動コミットを false に設定しないで commit() を呼び出すと、例外が返されないことに注意してください。
-
rollback()
rollback を実行すると、トランザクションが中止され、トランザクションによって変更されたすべての値が元の状態にリストアされます。
Note:
Native SDK for Java トランザクション・モデル
Native SDK for Java は、ここで説明した java.sql トランザクション・モデルに代わるトランザクション・モデルを提供します。Native SDK トランザクション・モデルは ObjectScript トランザクション・メソッドに基づいており、JDBC モデルと互換性はありません。トランザクションに Native SDK メソッド呼び出しが含まれる場合は、Native SDK モデルを使用する必要があります。詳細は、"Native SDK for Java の使用法" を参照してください。