...

JDBC SQLJ

by user

on
Category: Documents
88

views

Report

Comments

Description

Transcript

JDBC SQLJ
Page 1
1
JDBC/SQLJの
概要及び開発技法
Page 2
2
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 3
3
JDBC概要
JDBCとは?
l
l
JDBC とは、リレーショナル・データベースへの
問い合わせと更新を行うための標準Javaクラス
ライブラリ
JDBC の目的
– 特定のRDBMSに依存しないプログラムを記述
l
JDBC はODBCに準拠
l
JDBC で何ができるか
– データベースとの接続の確立
– SQL文の送信、実行結果の処理
JDBCは、SQL 文を実行するための標準 Java API です。これは、Javaプログラミング言語で書かれたク
ラスとインタフェースのセットで構成されます。
JDBCは、Java のアプリケーション開発者のための標準 API を提供し、特定のRDBMSに依存しないデー
タベースアプリケーションの作成を可能にします。
Java は、強固で安全であり、データベースアプリケーションのための非常に優れた基盤言語です。必
要なのは、Java アプリケーションが多種多様なデータベースとやり取りするための方法です。JDBC は、
これを行うための機構です。
型をサポートしました。
JDBCはODBCをベースにJavasoft によってモデル化され、SQL99のシンタックス・
JDBCはベンダ固有の拡張を考慮に入れており、Oracle ではいろいろな拡張をしています。
Page 4
4
JDBC概要
OracleのJDBCドライバ
l
Oracleは3つのJDBC ドライバを提供
– JDBC OCI ドライバ(クライアント側、TypeⅡ)
– JDBC Thin ドライバ(クライアント側、TypeⅣ)
– サーバ・ドライバ(サーバ側)
l
標準に準拠
– JDBC2.0に準拠
Ÿ 標準のJDBC APIに加え、独自の機能をサポート
Oracle は2つのクライアント用ドライバと、1つのサーバ用ドライバを提供しています。
クライアント側およびサーバ側のOracle JDBCドライバは、同じ機能を提供し、標準規格に準拠します。
また、標準のJDBC API に加え、独自の機能をサポートします。Oracle の JDBC ドライバが独自にサポー
トしているものには次のようなものがあります。
・ROWID、REFCURSOR、object-relational typesのような Oracle特有のデータ型
・JavaとPL/SQL のストアド・プロシージャへのアクセス
・全てのオラクル・
キャラクタ・セットのサポート
Page 5
5
JDBC概要
JDBC2.0の新機能
Ÿ バッチ更新
Ÿ ResultSetの機能拡張
– スクロール可能、更新可能なResultSet
Ÿ フェッチサイズ、行プリフェッチ
Ÿ JNDI によるデータベースのネーミング
Ÿ コネクション・プーリングのサポート
Ÿ 分散トランザクション/XA
Ÿ SQL3(SQL99) で扱われる各種データ型のサポート
JDBC2.0で、以下の新機能が使用可能になりました。
• バッチ更新
•ResultSetの機能拡張(スクロール可能、更新可能なResultSet)
•Javaオブジェクトの永続化
• フェッチサイズ、行プリフェッチ
•JNDI によるデータベースのネーミング
• コネクション・プーリングのサポート
• 分散トランザクション /XA
•SQL3(SQL99)で扱われる各種データ型のサポート
Page 6
6
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 7
7
3つのJDBCドライバ
OCIドライバ
l
l
l
主な対象:C/S型 Javaアプリケーション及び中
間層Javaアプリケーション
JDBC の呼び出しをOCI
の呼び出しに変換し
、Net8経由でデータベースに接続する。
特徴
– OCI libやNet8などのOracle クライア
ントのインストールが必要
– パフォーマンスが良い
– 全ての Net8アダプタを使用可能
Java Program
JDBC OCI Driver
OCI C Library
Net8
SQL Engine
PL/SQL Engine
インターフェース(OCI )を使うためのJDBCインターフェースです。Cの
OCI ドライバはオラクル・コール・
エントリ・ポイントを呼び出すため、プラットフォームに依存します。
OCI ドライバには、Net8 を含む、Oracle クライアントのインストールが必要です。
このドライバは、OCI を通してオラクル・
データベースとやりとりするため、Net8で接続できる全てのバー
ジョンのオラクル・データベースと接続できます。また、ローカル接続(
BEQ )とインストールされた全ての
Net8 アダプタ(IPC、Named Pipes、TCP/IP、IPX/SPX)をサポートします。
Page 8
8
3つのJDBCドライバ
Thinドライバ
l
l
l
l
主な対象:アプレット
ThinドライバがTCP/IPバージョンのNet8を独
自に実現して、データベースに接続する。
OCIドライバと同様の機能拡張
特徴
– クライアント側でのインストールが必要
ない
– Thinドライバのダウンロードに時間が
かかる
– Net8 TCP/IPプロトコルのみサポート
Java Program
JDBC Thin Driver
Java Sockets
Net8 TCP/IP
Listener
SQL Engine
PL/SQL Engine
Thin ドライバは、Java アプリケーションでの利用も可能ですが、事前にセットアップを必要としないので、
Java Applet での利用には理想的です。機能的にもOCI ドライバと同様の拡張がされております。
Thin ドライバは、TCP/IPバージョンのOracle Net8 を独自に実現(Java Socket の上にNet8及び
セットやデータの形式を必要に
TTC(Two-Task Common: クライアントとサーバ間の通信でキャラクタ・
応じて変換するレイヤー) をエミュレート)
しています。このドライバではTCP/IP プロトコルのみがサポート
されます。またTNS リスナーがデータベース・
サーバ上のTCP/IPソケットをリスニングする必要もあります。
Applet で利用される場合の動作
1. HTMLページからブラウザにJava Applet をダウンロード
2. JDBC Thin ドライバはApplet と共にブラウザにダウンロードされる
3. Applet が動作する時、直接、Net8 接続を確立
Page 9
9
3つのJDBCドライバ
サーバ・ドライバ
l
l
l
主な対象:Oracle8i内のJavaVM で動作し、デ
ータベースと通信するJavaプログラム
ネットワークを介してではなく、関数コールを使
用し、SQLエンジンにアクセスする。
Java Program
特徴
– ドライバ、JavaVM 、データベース、
KPRB C ライブラリ、SQLエンジン
は全て同じアドレス空間で動作
– デフォルトセッションを使用
Java Engine
JDBC Server Driver
KPRB C Library
SQL Engine
PL/SQL Engine
サーバ・ドライバの利用は、サーバ側でのみ可能です。サーバ・ドライバは、Java Stored Procedure 、
CORBA、Enterprise JavaBeans (EJB)等のデータベースに格納されたJava プログラムでSQL, PL/SQLを
利用することを可能とします。
サーバ・ドライバもクライアント側ドライバと同様の機能、拡張をサポートします。
サーバ・ドライバはデータベース内で動作するように最適化されており、データベースおよび SQLエン
ジンと同じアドレス空間で動作します。
SQL エンジンへのアクセスは関数コールであり、ネットワークは使
用しません。これにより、JDBCプログラムのパフォーマンスが向上し、SQLエンジンへのアクセスにリモー
トNet8 コールを実行するよりもはるかに高速です。
サーバ・ドライバを使用するには、すでに「
接続された」状態になっており、このドライバはそのデフォル
トのセッション内で動作します。
Page 10
10
3つのJDBCドライバ
最適なドライバの選択
l
OCIドライバ
– C/S Javaアプリケーション、中間層Javaアプリケーション
– パフォーマンスを望む場合
l
Thinドライバ
– アプレット
– 高い移植性を望む場合
l
サーバ・ドライバ
– Oracle8i内でのプログラム
(Java Stored Procedure, CORBA ・
EJB Objectなど)
Java アプリケーションやApplet で使用する JDBCドライバを選択する際に、次の点を考慮してください。
・Applet を作成する場合は、Thin ドライバを使用してください。OCI ドライバは実行する環境
での事前のインストールが必要ですので、選択できません。
・高い移植性を望む場合は、Thin ドライバを使用します。Thin ドライバを利用すると、アプリケー
ションとアプレットのどちらからでもOracle データベースに接続できます。
・アプリケーションのパフォーマンスを重視する場合は、OCI ドライバを使用してください。
・Oracle8i 内で動作するプログラムの場合は、サーバ・ドライバを使用してください。
Page 11
11
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 12
12
JDBCチュートリアル
JDBCを使用するための環境
l
CLASSPATH
– [Oracle Home]/jdbc/lib/classes12.zip
– NLSを使用する場合は下記も追加
[Oracle Home]/ jdbc/lib/nls_charset12.zip
l
OCIドライバ
– Solaris: LD_LIBRARY_PATH=[Oracle Home]/lib
– Windows NT: PATH=[Oracle Home]¥bin
l
Thinドライバ
– CLASSPATHの設定のみ
クライアント側の JDBCドライバ用に設定する環境変数について説明します。
インストールした JDBCドライバ用のCLASSPATH を指定する必要があります。使用しているJDK バージョ
ンに応じて、適切なCLASSPATH を指定してください。
Thin ドライバの場合は、CLASSPATH 以外の環境変数を指定する必要はありません。
OCI ドライバを使用する場合には、ライブラリー・パス環境変数に次の値を指定する必要もあります。
Solaris
LD_LIBRARY_PATH に[Oracle Home]/lib を追加
Windows NT
PATH に[Oracle Home]¥binを追加
Page 13
13
JDBCチュートリアル
JDBCを使用したプログラムの流れ
l
クエリーの実行手順
1. パッケージのインポート
2. JDBCドライバの登録
3. データベースへの接続
4. Statementオブジェクトの作成
5. クエリーの実行
6. 問い合わせ結果の処理
7. ResultSet、Statementオブジェクトのクローズ
8. データベースとの接続終了
Oracle JDBCドライバの起動および実行方法についてチュートリアルの形式で説明します。チュートリア
ルを実行することにより、クライアントからデータベースへの接続および問い合わせを行うJDBC Java コー
ドを作成できます。
Page 14
14
JDBCチュートリアル
JDBCを使用したプログラムの作成(1)
1. パッケージのインポート
import java.sql.*
JDBCパッケージ
– オラクル独自の拡張機能を使用する場合は下記も追加
import oracle.jdbc.driver.*
import oracle.sql.*
2. JDBC ドライバの登録
– JDBCドライバはDriverManagerに登録しなければならない
例:DriverManager.registerDriver(
new oracle.jdbc.driver.OracleDriver());
1. パッケージのインポート
使用する JDBCドライバの種類に関わらず、JDBC パッケージの import 文を記述する必要があ
ります。Oracle JDBCドライバの提供する拡張機能を使用する場合、Oracleパッケージを追加
する必要があります。
2. JDBCドライバの登録
使用するドライバをアプリケーションに登録するためのコードを記述する必要があります。この
例では、DriverManager クラスの static なregisterDriver() メソッドを使っています。別の方法と
して、java.lang.Class クラスのforName() メソッドを使用して JDBCドライバをロードすることも可
能です。
例:DriverManagerの1文を次の様に変更します。
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
} catch (ClassNotFoundException e) {...}
※ Class.forName() を使用する場合には例外処理を考慮しなくてはなりません。
Class.forName() メソッドを利用した場合は、実行時に動的にロードされるようになるため、次の
ような利点があります。
・ロードするクラス名を文字列で指定可能であるため、プログラムを修正することなく
JDBCドライバを任意に選択するようにする事が可能
・プログラム作成時に JDBC ドライバが無くともアプリケーションの作成が可能
JDBCドライバは、アプリケーション上で1度だけ登録します。
Page 15
15
JDBCチュートリアル
JDBCを使用したプログラムの作成(2)
3. データベースへの接続
– 接続するには、DriverManager を使用
–
getConnection(String URL,String user,String password);
– URLの書式は、jdbc:oracle:<drivertype>:@<database>
– 例 (OCI):Connection conn =
DriverManager.getConnection("jdbc:oracle:oci8:@ myHostString", "scott",
"tiger");
– 例 (Thin) :Connection conn =
DriverManager.getConnection("jdbc:oracle:thin:@myhost:1521:orcl", "scott",
"tiger");
4. Statementオブジェクトの作成
– 例:Statement stmt = conn.createStatement();
3. データベースへの接続
データベースへの接続を、DriverManager クラスの static な getConnection() メソッドを使用し
てオープンします。このメソッドは Connection クラスのオブジェクトを返します。
データベースURL 、ユーザID、パスワードを指定する書式
getConnection(String URL, String user, String password);
URLの書式は、”jdbc:oracle:type:@<database>”となります。
type は、thin もしくは oci8 を指定します。
database は、OCIドライバの場合はTNS名を指定し、thinドライバの場合は”host名:リ
スナーポート:SID”を指定します。
ユーザID 、パスワードをデータベースURLに含む書式
getConnection(String URL);
OCIドライバでデフォルト接続をする場合は、次のように記述します。
Connection conn = DriverManager.getConnection(
“jdbc:oracle:oci8:scott/tiger@”);
4. Statement オブジェクトの作成
データベースへ接続すると Connection オブジェクトを作成します。その後、Connection クラス
の createStatement() メソッドで、Statement オブジェクトを作成します。
Page 16
16
JDBCチュートリアル
JDBCを使用したプログラムの作成(3)
5. クエリーの実行
– StatementオブジェクトのexecuteQuery()メソッドを使
用
– executeQuery()メソッドは、1つのSQL問い合わせを
実行し、ResultSetオブジェクトを返す
– 例:ResultSet rset = stmt.executeQuery("select *
from EMP");
5. クエリーの実行
データベースへの問い合わせを行う場合、Statement クラスの executeQuery() メソッドを使用し
ます。このメソッドは、入力として SELECT 文を受け取り、ResultSet クラスのオブジェクトを返し
ます。
INSERT文, UPDATE文 , DELETE 文 , DDL文の実行
– executeUpdate()メソッドを使用
例:
INSERT
stmt.executeUpdate(
“insert into EMP(EMPNO, ENAME) values(100, ’jserver’”);
UPDATE
stmt.executeUpdate(
“update EMP set SAL = 10000 where EMPNO = 100”);
DELETE
stmt.executeUpdate(“delete from EMP where SAL > 10000”);
DDL 文
stmt.executeUpdate(
“create table test(id number(3), name(12))”);
Page 17
17
JDBCチュートリアル
JDBCを使用したプログラムの作成(4)
6. 問い合わせ結果の処理
– ResultSet オブジェクトは、SQL問い合わせから返される結果
セットを管理
– カーソルをサポート
– getXXX() メソッドを用いてデータを取りだし、結果を該当する
Java型にマッピング
– 例:
while(rset.next())
{
String ename = rset.getString(1);
…
}
6. 問い合わせ結果の処理
クエリーの実行後は、ResultSet オブジェクトの next() メソッドを使って、結果を反復します。こ
のメソッドは、結果セットを行ごとにループして、結果セットの最後に達するとそれを検出します。
next() メソッドは結果セットの最後に達するとfalse を返します。
データを取り出すには、ResultSet オブジェクトの getXXX() メソッドを使用します。引数には、
カラムの位置 もしくは カラムの名前 を指定してデータの取り出しが可能です。ここでのXXX
には、Java のデータ型が対応します。この例では String 型でカラムの位置を指定してデータ
を取りだしています。良く使用されるものには下記があります。
メソッド
Javaデータ型
SQLデータ型
getString()
getBigDecimal()
getByte()
getDate()
getInt()
getLong()
java.lang.String
java.math.BigDecimal
byte
java.sql.Date
int
long
VARCHAR2
NUMBER
CHAR
DATE
NUMBER
NUMBER
Page 18
18
JDBCチュートリアル
JDBCを使用したプログラムの作成(5)
7. ResultSet, Statementオブジェクトのクローズ
– ResultSet、Statementオブジェクトは、使い終わった
ら明示的にクローズしなくてはならない
– 例:rset.close();
stmt.close();
8. データベースとの接続終了
– 作業が完了したら、データベースとの接続を終了し
なくてはならない
– 例:conn.close();
7. ResultSet, Statement オブジェクトのクローズ
ResultSet とStatement オブジェクトの使用後に、明示的にこれらをクローズする必要がありま
す。これは、JDBCドライバを使用して作成したすべてのResultSet および Statement オブジェク
トに適用されます。
JDBCドライバではリソースは暗黙的に解放されません。そのため、クリーンアップ・ルーチンは、
ResultSet および Statement クラスの close() メソッドを使って実行します。明示的にオブジェクト
のクローズをしないと、深刻なメモリ・リークが発生する場合があります。ResultSetオブジェクト
のクローズを行うと、データベース内の対応するカーソルが解放されます。
8. データベースとの接続終了
作業が完了したら、データベースへの接続を終了する必要があります。これは、Connection ク
ラスの close() メソッドを使って実行します。クライアント側でConnection クラスの close() メソッド
が呼ばれるまで、データベースとのセッションは保持されます。
Page 19
19
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 20
20
JDBC サンプル・ソース
import java.sql.*;
class emp
{
public static void main(String args[]) throws SQLException
{
// JDBCドライバのロード、ドライバの登録
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
// データベースへの接続
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@myhost:1521:orcl", "scott", "tiger");
// Statementオブジェクトの作成
Statement stmt = conn.createStatement();
// クエリーの実行 (EMPテーブルの全てのカラム)
ResultSet rset = stmt.executeQuery("select * from EMP");
// メタデータの取得
ResultSetMetaData rsmd = rset.getMetaData();
// カラム数の取得
int numCols = rsmd.getColumnCount();
// カラム名の出力
for (int i=1; i<=numCols; i++)
{
if (i > 1) System.out.print(",");
System.out.print(rsmd.getColumnLabel(i));
}
System.out.println("");
// 問い合わせ結果の処理
while (rset.next())
{
for (int i=1; i<=numCols; i++)
{
if (i > 1) System.out.print(",");
// 問い合わせ結果の出力
System.out.print(rset.getString(i));
}
System.out.println("");
}
// ResultSet、Statementオブジェクトのクローズ
rset.close();
stmt.close();
// データベースとの接続終了
conn.close();
}
}
Page 21
21
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 22
22
SQLJ概要
SQLJとは?
l
l
静的なSQL操作をJava コードに埋め込むことが
可能
何ができるか
– 埋め込みSQLの構文チェック
– データ型のチェック
– セマンティクスの確認
SQLJ はPro*Cのようなプリコンパイラと概念的に似ていて、Java プログラムにSQL文を埋め込むことが
できます。トランスレータ(
プリプロセッサ)を実行し、SQLJコードからJDBCコールを含むJavaコードを生
成します。SQLJでは全てのベンダのJDBCドライバが使用可能です。
SQL文を Javaコードに直接埋め込む SQLJ方式は、JDBC方式より扱いやすく簡潔です。
SQLJを使用
すると、データベース接続を必要とするJavaプログラムの開発費とメンテナンス費を節約できます。
SQLJ トランスレータでは、次のチェックを行います。
・埋め込み SQLの構文チェック
・データ型のチェック (Java とSQL 間で型変換が適切に行われることの確認)
・セマンティクスの確認 (
SQL の構文とデータベース・スキーマの比較)
※ JDeveloperではSQLJ アプリケーションの開発・デバッグ等の開発環境を提供
Page 23
23
SQLJ概要
OracleのSQLJ
l
標準に準拠
l
Oracleの拡張
– 標準以外のデータ型のサポート
– データベース内のJavaVM での実装
SQLJは、Oracle、IBM、Tandem 、Sybase、Infomix、Javasoft をはじめとするベンダーで共同開発されて
います。ANSI/ISOに SQLJ 言語仕様を提出し、スタンダードとしての地位を確立しています。
Oracle SQLJ では、ANSI SQLJ標準以外のSQL文も使用できます。ANSI SQLJ標準は、SQL92 のみを
規定していますが、拡張も許容しています。Oracle SQLJでは、Oracleの SQL言語を使用できます。デー
タ型は、LOB(BLOB, CLOB, BFILE) 、ROWID 、REF CURSORなどの Oracle 固有のデータ型もサポー
トされます。
また、データベース内のJava VMでもSQLJ を実装することにより、Java のストアド・プログラムでの使用
が可能となっています。
Page 24
24
SQLJ概要
JDBC vs. SQLJ
JDBC
SQLJ
java.sql.PreparedStatement stmt;
ResultSetIterator results;
ResultSet results;
#sql results =
stmt = conn.prepareStatement
{SELECT ename FROM emp
(“SELECT ename FROM emp
WHERE sal > :salparam
WHERE sal > ? AND deptno = ?”);
AND deptno = :deptnoparam};
stmt.setInt(1, salparam);
stmt.setInt(2, deptnoparam);
results = stmt.executeQuery();
SQLJコードは JDBC コードと比較するとはるかに簡潔で生産的です。
記述するコードの量が増えると、当然エラーの確率も上がります。
SQLJは下記の方法で開発者の生産性を改善します。
•JDBCよりコンパクトなコード
• SQL 文を直接埋め込む
• SQL 文中でJavaのバインド変数や表現を使用可能
• default connectionをサポート
• JDBC Statementオブジェクトを意識する必要がない
• 早い段階でのチェック
• JDBCでは実行時まで確認できなかったSQL文の構文チェック、データ型の チェック等を開
発時に行う
Page 25
25
SQLJ概要
JDBCとSQLJ
l
JDBC+SQLJ は補完的な関係
– SQLJは静的SQLのためのより簡潔なシンタックスを
提供
– 動的SQLはJDBC で記述
– 1つのプログラムでSQLJとJDBCの混在が可能
SQLJ は JDBCと比較して簡潔なシンタックスを提供しますが、これは静的 SQLのためのものであり、動
的 SQLでは使用できません。動的 SQLを使用するには JDBCで記述する必要があります。
そのため、SQLJ では、JDBC との混在が可能なように考慮されています。SQLJ とJDBCが連係動作を
するために、SQLJ 接続コンテキストからJDBC接続への変換とSQLJイテレータから JDBC ResultSet
への変換が可能となっております。
※ JDBC ドライバはどのベンダーのドライバでも使用できます。ただし、Oracle 固有の データ型や機
能を使用する場合は、Oracle JDBCドライバを使用してください。
Page 26
26
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 27
27
SQLJの構成
SQLJのコンポーネント
l
SQLJのコンポーネント
– トランスレータ
– ランタイム
l
SQLJ
SQLJ
Application
Application
SQLJ
SQLJ runtime
runtime
SQLJプロファイル
– SQL操作に関する詳細情報
Any
Any
JDBC
JDBC
Driver
Driver
Any
RDBMS
Oracle SQLJ は、次の2 つの主要コンポーネントで構成されています。
Oracle SQLJトランスレータ
このコンポーネントは、SQLJコードからJava コードを生成するためのプリプロセッサ(プリコンパ
イラ)
です。
SQLJコードのファイルの拡張子は、必ず .sqlj にしましょう。
Oracle SQLJランタイム
エンド・
ユーザが SQLJ アプリケーションを実行する際に、このコンポーネントが起動します。
このコンポーネントは JDBCドライバを介してデータベースにアクセスします。このアクセス方法
は、汎用SQLJ標準の規定ではなく、Oracle SQLJランタイムの要件です。
コンポーネントは、純粋な Java コードから成るThin レイヤーで、JDBCドライ
SQLJ ランタイム・
バの上で動作します。
SQLJ プロファイル
SQLJプロファイルは、シリアライズされたJavaオブジェクトであり、SQLJトランスレータによって
生成されます。プロファイルの内容は、SQLJ コードに埋め込まれているSQL 操作に関する情
報やアクセスするデータの型やモードに関する情報で、プログラム実行時にランタイム・
コンポー
ネントより使用されます。
SQLJプロファイルの拡張子は通常 .ser になります。
Page 28
28
SQLJの構成
SQLJトランスレーション処理
SQLJ
コード
SQLJ
トランスレータ
JDBC
コールを
含む
Java コード
Java
コンパイラ
Java
クラス
ファイル
Oracle8i
l
l
トランスレータが、JDBCコールを含む標準的な
Java コードを生成
早い段階での SQL文、データ型等のチェック
SQLJ アプリケーションを作成するために、開発者はまず、SQLJ トランスレータを用いて SQLJ コード
からJDBCコールを含む標準的な Java コードを生成します。開発者は、SQLJ オプションの設定により、
オンライン・チェックまたはオフライン・チェックを指定できます。オンライン・チェックでは、データベース
に接続され、アプリケーションで使用されるデータベース表、ストアド・
プロシージャ、SQLの構文などが
すべて問題ないかどうかが検証されます。
SQLJ プログラムの変換処理は次のようなステップで処理されます。
1. SQLJ トランスレータを起動
2. sqlj ファイル内のコード解析と構文チェック
SQLJ 構文が検証され、セミコロンの抜け、中カッコの対の抜け、明らかな型の不一致
などがチェックされます。
3. セマンティクス・チェック
埋め込み SQL文のセマンティクスがチェックされます。
コールに変換し、Java コードと SQLJプロファイルを生成
4. SQL 操作を SQLJ ランタイム・
コンパイラ(通常は
を起動し、ステッ
5. Java
Sun MicrosystemsのJDKで提供される標準 javac)
プ4で生成された Javaコードがコンパイルされます
6. プロファイルのカスタマイズ
ベンダー固有のデータ型や機能を使用できるようにします
Page 29
29
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 30
30
SQLJを使用した開発
SQLJを使用するための環境
l
CLASSPATH
– JDBCでの設定
– [Oracle Home]/sqlj/lib/translator.zip
– SQLJアプリケーションの実行には、ランタイム・クラ
スが必要です。ランタイム・クラスは次のファイルに
含まれています。
[Oracle Home]/sqlj/lib/runtime.zip
l
PATH
– [Oracle Home]/bin
Oracle SQLJ を使用する前提条件として、下記があります。
• システム上で標準 Java環境が必要です。(通常はSun MicrosystemsのJDK )
JDK のバージョンは1.1.x と1.2.x をサポートします。1.0.2は未サポートです。
• 使用している環境で、JDBCアプリケーションを実行できる必要があります。
java.sql JDBCインターフェースを実装するJDBCドライバが必要です。
JDBCドライバを使用してアクセス可能なデータベースが必要です。
Oracle SQLJ を使用するには、CLASSPATH とPATHを設定する必要があります。
Page 31
31
SQLJを使用した開発
SQLJ開発ステップの流れ
l
開発ステップ
1. SQLJプログラムを記述
2. SQLJプログラムを変換
3. SQLJアプリケーションの実行
Page 32
32
SQLJを使用した開発
SQLJアプリケーションの開発ステップ(1)
l
SQLJプログラムの記述
– SQLJ句の使用
– JavaにSQL文を埋め込むための標準的な構文
で記述される実行可能なSQLJ文
– 全ての SQLJ句は‘#sql’で始まる
– {}内にSQL文を記述する
– 全ての SELECT文、DML文、DDL文が埋め込
み可能
– SQL文中でJavaの変数を使用
– バインド変数は‘:’の後に続ける
SQLJ プログラムでのSQL文の例を示します。
基本的な SQL
#sql { INSERT INTO EMP(ENAME) VALUES (’Joe’) };
PL/SQLブロック
#sql {
DECLARE
n NUMBER;
BEGIN
n := 1;
WHILE n <= 100 LOOP
INSERT INTO EMP(EMPNO) VALUES (2000 + n);
n := n + 1;
END LOOP;
END;
};
バインド変数
String name = “SMITH“;
double salary = 25000.0;
...
#sql { UPDATE EMP SET SAL = :salary WHILE ENAME = :name };
Page 33
33
SQLJを使用した開発
SQLJアプリケーションの開発ステップ(2)
l
SQLJプログラムの変換
– SQLJトランスレータを実行
– コマンドラインで実行
– SQLのチェックを行う
– オプションの指定
l
SQLJアプリケーションの実行
2. SQLJ プログラムを変換
SQLJ コードが完成したら、SQLJ トランスレータを実行して SQLJプログラムをJava プログラムに変換し
ます。例えば、ソース・ファイルが sample.sqlj であった場合、下記のようにコマンドラインから実行します。
> sqlj sample.sqlj
例えば下記のようなコードではオンライン・
チェックで不整合エラーが発生します。
Date d = new Date(1993, 3, 11);
#sql {insert into EMP values (:d)}
※ 同じ内容のJDBC プログラムは実行時にエラーが発生します。
オプションの指定は、コマンドラインまたはプロパティ・ファイルにて行います。例えば、プロパティ・
ファ
イルでユーザー名を指定し、コマンドラインでパスワードを指定する事ができます。
3. SQLJ アプリケーションの実行
トランスレーション処理で生成されたSQLJ アプリケーションを実行します。アプリケーションからSQLJ
ランタイムが呼び出されます。SQLJ ランタイムは該当するSQL操作をプロファイルから読み込みます。
その後、SQLJ ランタイムが JDBCドライバを呼びだし、SQL操作を JDBC ドライバに渡します。
Page 34
34
SQLJを使用した開発
SQLJでの検索
l
SQLJイテレータの使用
– 名前指定イテレータ
– 位置指定イテレータ
– イテレータの使用手順
1.イテレータの宣言
2.イテレータ・クラスのインスタンスを定義
3.SELECT文を使用し、イテレータ変数に結果を
取り込む
4.イテレータの検索列にアクセスする
5.イテレータを閉じて、リソースを解放
SQLJ プログラムで複数行の問い合わせ結果を処理するには、SQLJ イテレータが必要です。イテレー
タには宣言の方法で名前指定イテレータと位置指定イテレータの2種類存在します。それぞれに利点
があり、使用目的も異なります。
名前指定イテレータは、SELECTフィールドとイテレータ列は名前で一致する必要があります。そのた
め、問い合わせのカラム順を意識する必要がありません。データが誤った列に取り込まれる事がないた
め、エラーが少なくなります。データの取り込みにnext() メソッドを使用します。
位置指定イテレータは、他の埋め込みSQL言語と同様のパラダイムや構文が使用可能です。例えば、
データの取り込みにFETCH INTO 構文を使用します。データを名前ではなく、位置で取り込むため、問
い合わせのカラム順に注意する必要があります。
それぞれの例については、次ページを参照してください。
Page 35
35
イテレータの例
名前指定イテレータ
// イテレータの宣言
#sql iterator EmpIter(String ENAME, double SAL);
...
// イテレータ・クラスのインスタンスを定義
EmpIter emps;
#sql emps = { select SAL, ENAME from EMP };
// 結果の操作
while(emps.next())
{
String ename = emps.ENAME(); // “ENAME”, “SAL”は宣言と完全に一致
double sal = emps.SAL(); // 大文字です。 “ename”, “sal”ではありません。
...
}
emps.close();
位置指定イテレータ
// イテレータの宣言
#sql iterator EmpIter(String, double);
...
// ホスト変数の定義
String name = null;
double salary = 0;
// イテレータ・クラスのインスタンスを定義
EmpIter emps;
#sql emps = { select ENAME, SAL from EMP };
// 結果の操作
while(true)
{
#sql { FETCH :emps INTO :name, :salary };
// endFetch()メソッドでデータの終わりに達したかどうかを確認します。
// これは、必ずFETCH INTO文の後で行う必要があります。
if (emps.endFetch()) break;
System.out.println(“Name is “ + name);
...
}
emps.close();
Page 36
36
SQLJを使用した開発
プログラミング上の注意事項
l
名前の制限
l
NULLの処理
l
例外処理
l
トランザクション制御
プログラミング上の主な注意事項について説明します。
名前の制限
文字列 “__sJT_“は、SQLJ で生成した変数名のプレフィックスとして予約されています。また、
java 、sqlj、oracle などのアプリケーションで使用するパッケージ名はクラス名として使用できま
せん。
NULLの処理
Java の基本型(int, double, float など)は規約上、NULL 値をとることができません。データベー
スからのデータ受信時に、SQLのNULLが Java のNULLに変換されます。SQLのNULLが受
信されそうな場合は、Java の基本型を出力変数として使用しないでください。基本型のかわり
に、次のラッパークラスを使用します。
•java.lang.Boolean
•java.lang.Byte
•java.lang.Short
•java.lang.Integer
•java.lang.Long
•java.lang.Double
•java.lang.Float
例外処理
SQLJ プログラムは JDBC コールを含む Java コードです。したがって、SQLJ でも SQLJ 構文を
含むブロックで適切な例外処理を組み込む必要があります。
トランザクション処理
コミットおよびロールバックは、開いている結果セットとイテレータには反映されません。内容は
SELECT文を実行したときの状態が引き続き反映されています。(データベース・アプリケーショ
ンでの一般的な注意事項です)
Page 37
37
JDBC/SQLJの概要及び開発技法
目次
l
JDBC
–
–
–
–
l
JDBC概要
3つのJDBC ドライバ
JDBCチュートリアル
JDBCサンプル
SQLJ
–
–
–
–
SQLJ概要
SQLJの構成
SQLJを使用した開発
SQLJサンプル
Page 38
38
SQLJ サンプル・ソース
import java.sql.*;
import sqlj.runtime.*;
import oracle.sqlj.runtime.Oracle;
class sample
{
public static void main(String args[]) throws SQLException
{
// オラクルへの接続 'sqlj.properties'でスキーマの指定などを行う
Oracle.connect(sample.class, "sqlj.properties");
// ResultSetオブジェクトへ変換するためのイテレータ
ResultSetIterator rsiter;
#sql rsiter = { SELECT * FROM EMP };
// ResultSetオブジェクトを取得
ResultSet rset = rsiter.getResultSet();
// メタデータの取得
ResultSetMetaData rsmd = rset.getMetaData();
// カラム数の取得
int numCols = rsmd.getColumnCount();
// カラム名の出力
for (int i=1; i<=numCols; i++)
{
if (i > 1) System.out.print(",");
System.out.print(rsmd.getColumnLabel(i));
}
System.out.println("");
// 問い合わせ結果の処理
while (rset.next())
{
for (int i=1; i<=numCols; i++)
{
if (i > 1) System.out.print(",");
// 問い合わせ結果の出力
System.out.print(rset.getString(i));
}
System.out.println("");
}
// ResultSetIteratorオブジェクトのクローズ
// ResultSetもクローズされます
rsiter.close();
}
}
Page 39
39
SQLJ プロパティ・ファイル (sqlj.properties )
###
### 詳細は、『
SQLJ開発者ガイドおよびリファレンス』 マニュアル
「第8章 トランスレータのコマンド行とオプション」を参照して下さい。
###
###
###
### Settings to establish a database connection for online checking
###
### turn on checking by uncommenting user
### or specifying the -user option on the command line
sqlj.user=scott
sqlj.password=tiger
### add additional drivers here
sqlj.driver=oracle.jdbc.driver.OracleDriver
### Oracle JDBC-OCI7 URL
#sqlj.url=jdbc:oracle:oci7:@
### Oracle JDBC-OCI8 URL
sqlj.url=jdbc:oracle:oci8:@
### Oracle JDBC-Thin URL
#sqlj.url=jdbc:oracle:thin:@<host>:<port>:<oracle_sid>
#sqlj.url=jdbc:oracle:thin:@localhost:1521:orcl
### Warning settings
### Note: All settings must be specified TOGETHER on a SINGLE line.
### Report portability warnings about Oracle-specific extensions to SQLJ
#sqlj.warn=portable
### Turn all warnings off
#sqlj.warn=none
### Turn informational messages on
#sqlj.warn=verbose
### Online checker
###
# JDBC-generic checker:
sqlj.online=sqlj.semantics.JdbcChecker
### Offline checker
###
#sqlj.cache=on
Page 40
40
Page 41
41
Fly UP