
新人SEのためのJava講座
Javaデータアクセスの基礎
佐藤直生
日本オラクル
2001/8/18
| 第3回 JDBCによる更新処理の実行 |
|
この連載では、Javaのデータベース・アクセスAPIである「JDBC」の機能を、サンプルコードを交えて解説していきます。また、J2EEにおけるJDBCの位置付けや、JDBCを利用するさまざまなテクノロジについても解説していく予定です。前提知識としては、Javaとリレーショナル・データベースに関するベーシックな知識があれば十分です。 |
|
今回の内容
|
| |
前回は、JDBCでデータベースに接続し、検索(select文)を実行するサンプルを紹介しました。今回は、DDL文やDML文を実行するサンプル・コードを見ながら、これらの処理について解説をしていきます。併せて、例外処理やトランザクションについても、取り上げます。
最初に、DDL(データ定義言語:Data Definition Language)について見ていきましょう。DDL文には、表やビューをはじめとするデータベース・オブジェクトの作成(create文)、変更(alter文)、削除(drop文)などがあります。以下のサンプル・コードでは、SCOTTスキーマに、EMPLOYEE表とPL/SQLストアド・プロシージャを作成しています。
// Javaデータアクセスの基礎
サンプル・コード(2) import java.sql.*;
|
リスト JavaDataAccess02.java
|
このコードを、2回続けて実行すると、次のようになります。
C:\JDBC>java JavaDataAccess02 エラー・コード: 955 |
では、順を追ってコードを見てみましょう。データベース接続を確立するコードは、前回紹介したサンプル・コード(JavaDataAccess01.java)と同様です。
select文の実行にはexecuteQuery()メソッドを利用しましたが、DDL文の実行にはexecuteUpdate()メソッドを利用します。ここでは、(EMP表とほぼ同じ構造の)EMPLOYEE表、およびストアド・プロシージャ(特定の部門番号(DEPTNO列)の社員の給与(SAL列)の増加率(%単位)を受け取り、EMPLOYEE表をupdateする)を作成しています。
sql_str
= "create table EMPLOYEE ..."; sql_str = "create or
replace procedure RAISE_SAL ..."; |
select文の場合とは違い、問い合わせ結果はありませんので、executeUpdate()メソッドはResultSetオブジェクトを返しません。
JDBC APIで、データベース・アクセスを行うすべてのメソッドは、データベース・エラーが発生したときに、java.sql.SQLException例外をthrowします。
前回のコード(JavaDataAccess01.java)では、mainメソッドで、SQLException、およびjava.lang.Class.forNameメソッドがthrowするjava.lang.ClassNotFoundExceptionを、そのままthrowさせていました。
public
static void main (String args[]) |
今回のコードでは、例外をcatchし、標準出力にエラー・メッセージを出力しています。
さらに、catchした例外がSQLExceptionの場合には、getErrorCode()メソッドで、データベース・ベンダ固有のエラー・コードを取得し出力しています。
try { ...
|
このコードの2回目の実行時には、EMPLOYEE表がすでに存在しているため、create table文を実行するexecuteUpdate()メソッドでSQLExceptionが発生し、次の出力が生成されます。
java.sql.SQLException:
ORA-00955: すでに使用されているオブジェクト名です。 エラー・コード: 955 |
これを見れば分かるように、Oracleデータベースの場合には、getErrorCode()メソッドが返すエラー・コードは、最大5けたのエラー番号(ORA-xxxxx)となります。
続いて、DML(データ操作言語:Data Manipulation Language)文について見ていきましょう。
DML文には、表やビューなどのデータベース・オブジェクト内のデータに対する、クエリ(select文)、挿入(insert文)、変更(update文)、削除(delete文)などがあります。以下のサンプル・コードでは、EMPLOYEE表に対してさまざまなDML文を実行しています。
// Javaデータアクセスの基礎
サンプル・コード(3) // JDBC APIをインポート
|
リスト JavaDataAccess03.java
|
JavaDataAccess02を実行して、EMPLOYEE表を作成した後にこのコードを実行すると、次のようになります。
C:\JDBC>java JavaDataAccess03 |
では、順を追ってコードを見てみましょう。select文を除くDML文の実行には、DDL文と同様に、executeUpdate()メソッドを利用します。また、executeUpdate()メソッドは、DML文によって変更された行数を返します。ここでは、delete文、insert文、update文を実行し、変更行数の取得も行っています。
sql_str
= "delete from EMPLOYEE"; |
JDBCでのトランザクションを取り上げる前に、「トランザクション」について簡単にまとめておきましょう。
トランザクションとは、一連のデータ処理を1つの単位として管理することを指しています。例えば、銀行の口座管理システムでは、「口座Aから口座Bへの振替」は、「口座Aから引き落とす」「口座Bへ振り込む」という複数の処理を含む、1つのトランザクションである、といえます。
トランザクションは、次の4つの特性を持っています(通常、各属性の頭文字を取って「ACID特性」といわれます)。
(1)原子性(Atomicity)
トランザクションは、処理が完全に完了するか、あるいは一切実行されないかのいずれかである必要があります。
リレーショナル・データベースでは、一連のDML処理に続いて、COMMITコマンドを実行することによって、トランザクション開始後のすべての変更内容が永続的に保存されます(トランザクションのコミット)。代わりに、ROLLBACKコマンドを実行すると、トランザクション開始後のすべての変更内容が取り消されます(トランザクションのロールバック)。
(2)一貫性(Consistency)
トランザクションは、データの一貫性を破壊してはなりません。データの一貫性とは、データが整合性のとれた状態であることを指します。
リレーショナル・データベースでは、制約、ストアド・プロシージャ、トリガなどを利用して、一貫性を維持することが多いでしょう。
(3)独立性(Isolation)
同時に実行されている複数のトランザクションは、互いに影響を及ぼしてはなりません。トランザクションが1つずつ順番に実行された場合と、同じ結果になる必要があるわけです。
リレーショナル・データベースでは、ロックやバージョニングといわれるテクノロジを利用して、トランザクションの独立性を保障しています。
(4)耐久性(Durability)
コミットされたトランザクションの結果は、耐久性のある方法で保存されなくてはなりません。耐久性とは、障害などが発生してもその内容が失われることがない、という意味です。
多くのデータベースは、ログ・ファイル(Oracleデータベースでは「REDOログ・ファイル」)に、トランザクションの変更履歴を随時書き込むことによって、トランザクションの耐久性を保障しています。
JDBCのデータベース接続には、「自動コミット・モード」という概念があります。
自動コミット・モードがオン(true)の場合、SQL文を実行するたびに、自動的にコミットされます。トランザクション管理が必要でない場合は、こちらが便利です。しかし、コミット処理の回数が増えるため、パフォーマンスの悪化を招くことがあります。
一方、自動コミット・モードがオフ(false)の場合は、手動でコミットやロールバックを実行する必要があります。トランザクション管理が必要な場合には、当然こちらを利用する必要があります。
自動コミット・モードを設定するには、java.sql.ConnectionオブジェクトのsetAutoCommit()メソッドを利用します。デフォルト値はtrueであることに注意しましょう。
// 自動コミット・モードを設定 |
トランザクションのコミットおよびロールバックには、それぞれcommit()メソッド、rollback()メソッドを利用します。
// トランザクションをコミット |
サンプル・コードでは、更新処理の後にロールバックを実行しています。実際にロールバックされていることは、コードの実行結果を見れば分かるでしょう。
sql_str
= "update EMPLOYEE ..."; |
catch節の中でロールバックを実行するようにしておけば、「例外が発生しなければコミットし、例外が発生すればロールバックする」という振る舞いを実装できます。これによって、JDBCアプリケーションでトランザクションの原子性を保証することが可能となるわけです。
try {
// トランザクションをコミット // 例外を処理 // 接続がクローズされていない場合、
|
次回は、PreparedStatementやCallableStatement(ストアド・プロシージャの実行)を取り上げる予定です。
| ■参考リファレンス |
次回、「Javaデータアクセスの基礎」の掲載は9月上旬頃になります
| 連載記事一覧 |
TechTargetジャパン
- Scalaのパッケージ、アクセス修飾子、オブジェクト継承 (2012/5/22)
インポート、パッケージオブジェクト、抽象クラス/抽象メソッド、オーバーライド、final、シールドクラスなども - 基幹系システムでCloud SQLは使えるか試してみた (2012/5/17)
サンプルとしてMRPシステムを作成して動かし、「再帰呼び出し」などのパフォーマンスを測定して検証してみます - アジャイル管理ツール9選+Pivotal Tracker入門 (2012/5/14)
群雄割拠のアジャイルプロジェクト管理ツールを9つ紹介し、特に注目を集めているPivotal Trackerの基本的な使い方を解説します - サーバサイドJSやJavaでWebアプリが作れるXPages (2012/5/11)
Notes/Dominoの資産をサーバサイドJavaScriptやJavaで操作し、HTMLやJavaScript、CSSをUIにできる技術を紹介
|
|
キャリアアップ
スポンサーからのお知らせ
- - PR -
イベントカレンダー
- - PR -
