[???] /
[Java FAQ] / [S135]
S135: JDBC(プログラミング)
[S135 Q-01]
java.sql.ResultSet をシリアライズすることはできますか?
[S135 A-01]
java.sql.ResultSet 自体をシリアライズすることはできません。JDBC 2.0
から Optional Package として、シリアライズ可能な RowSet というインタ
フェースが提供されるようになりましたので、これを利用するといいでしょう。
ただし、RowSet 自体はインタフェースでしかありませんので、、別途実装を
入手する必要があります。JavaSoft から CachedRowSet という実装の Early
Access 版が提供されていますし、商用の JDBC ドライバの中には RowSet の
実装を提供しているものもあります。
・JDBC 2.0 Optional Package 入手先
http://www.javasoft.com/products/jdbc/download.html
・CachedRowSet 入手先
http://developer.java.sun.com/developer/earlyAccess/crs/
ネットワーク経由で java.sql.ResultSet を操作したいだけであれば、RMI を
使ってネットワーク経由で ResultSet を操作する例が以下の URL で紹介され
ています。
・JDBC Note
http://www02.so-net.ne.jp/~kikuta/jdbcnote/jdbcnote.html
[S135 Q-02]
java.sql.ResultSetで取得したデータの数を得たいのですが?
[S135 A-02]
以下の方法が考えられます(WHERE 句で指定した条件に該当する行の件数をカウ
ントする例です)。
- ResultSet を先頭から順番に読み込んで、自分で件数をカウントする。
Statement stmt = .... // Statement オブジェクトを取得する処理。
ResultSet rs = stmt.executeQuery("SELECT * FROM 表名 WHERE 条件式");
int count = 0;
while(rs.next()) {
count++;
}
- ResultSet を作成する SELECT 文に COUNT(*) を入れておいて、その値を参
照する。
Statement stmt = .... // Statement オブジェクトを取得する処理。
ResultSet rs = stmt.executeQuery(
"SELECT COUNT(*) FROM 表名 WHERE 条件式");
rs.next();
// 行数を取得する。
int count = rs.getInt(1);
- JDBC 2.0 とスクロール可能な ResultSet が使える場合は、カーソルを最終
行に移動して、ResultSet#getRow() メソッドを呼び出す。
Connection con = .... // データベースとの接続を確立する処理。
// 以下の Connection#createStatement() メソッドが実行可能かどうか
// は JDBC ドライバの実装に依存します。
Statement stmt = con.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT * FROM 表名 WHERE 条件式");
rs.last();
int count = rs.getRow();
[S135 Q-03]
JDBCでSELECTした件数を取得したいのですが?
[S135 A-03]
S135-02 を参照してください。
[S135 Q-04]
「java.util.*」と「java.sql.*」を同時にimportするとエラーになるのはなぜ?
[S135 A-04]
import java.util.*;
import java.sql.*;
としてDateクラスを使おうとすると、どちらのパッケージの Date クラスか明
確でない(両方のパッケージに Date というクラスが存在する)ために上記のエ
ラーを出します。java.sql.Date を使いたい場合は、
import java.util.*;
import java.sql.*;
import java.sql.Date;
と java.sql.Date を明示的に import してください(逆なら java.util.Date
を明示的に import します)。
[S135 Q-05]
java.sql.Date#getTime() メソッドが返す値は、環境によって GMT になったり
JST になります。なぜ?
[S135 A-05]
java.sql.Date クラスは年月日を扱うクラスで時分秒は無視して使用するもので
す。java.sql.Date の API ドキュメントにも、時刻部分は 0 でクリアして使用
するように書かれています。
Oracle 等の一部の RDBMS では、SQL の DATE 型で時刻も表わすようになって
います。このような場合で、日付と時刻両方を扱いたい場合は
java.sql.Timestamp を使用してください。時刻のみを扱いたい場合は
java.sql.Time を使用してください。
[S135 Q-06]
java.sql.ResultSet で取得したデータが SQL の NULL かどうかを判別したい
のですが?
[S135 A-06]
java.sql.ResultSet#wasNull() を使用してください。ただし、このメソッドは
ResultSet#getXXX() メソッドを使用して取得したデータが NULL だったのかど
うかしか判断できないことに注意してください。
ResultSet#isNull(int) のような任意の列が NULL かどうかを判定できるよう
なメソッドは JDBC では提供されていません。ResultSet#isNull(int)が提供で
きなかった理由については、JDBC のドキュメントに詳しい記述があります。
・java.sql.ResultSet#isNull(int) が提供されなかった理由
http://java.sun.com/products/jdk/1.2/ja/docs/ja/guide/jdbc/spec/jdbc-
spec.frame15.html
[S135 Q-07]
大量のデータを更新したいのですが、ネットワークの負荷が気になります。解決策は?
[S135 A-07]
ネットワークの負荷が問題になる場合やオフラインで運用する場合は、クライ
アント側のプログラムで対処せずに DBMS の Replication 機能を使うのが一
般的な解決方法です。最新の RDBMS では何らかの形で Replication をサポー
トしていますし、安価な PC 用 RDBMS は Replication を前提に作られている
ものが多くあります。
contributor: m-nakamura
コメントの送り先:Java FAQ BBS