JDBC接続サンプル(+雑談)
JDBCで接続してSQL発行するプログラムのサンプル。(データソースを使う)
その辺探せばどこにでもあるけど個人の備忘録として。
// ①データソースの生成
OracleConnectionPoolDataSource opds = new OracleConnectionPoolDataSource();
// ②DBのURLを設定
opds.setURL("jdbc:oracle:thin:@192.168.0.100:1521:TESTDB");
// ③DB接続ユーザーを設定
opds.setUser("TESTDBUSER");
// ④DB接続パスワードを設定
opds.setPassword("TESTDBPASS");
// ⑤Connection生成
Connection con = opds.getConnection();
// ⑥Statement生成
Statement st = con.createStatement();
// ⑦SQL実行+ResultSetをもらう
ResultSet rs = st.executeQuery("SELECT ID,NAME FROM EMP");
// ⑧とりあえず全フェッチ
while(rs.next()) {
//何もしない
}
// ⑨close
st.close();
rs.close();
con.close();
この例では192.168.0.100のIPにあるTESTDBに接続して、
EMP表からIDとNAME項目とってきてとりあえず全フェッチする。
EMP表というのはこの手の例で毎回つかわれるのでそれにあやかっただけです。
この例ではOracleConnectionPoolDataSourceを使って接続します。
これは前のプロジェクトで実際に使ってたから。
WEBシステムではよく使われてるやつでしょうね。
よくある「SQL単体だと早いけどJDBCから実行すると遅い」というタイプの問題の検証にあたって
簡単なプログラム作って検証してみたものの一部抜粋という感じです。
「SQL単体だと早いけどJDBCから実行すると遅い」というのは
少なくとも私が経験したプロジェクトでは毎回話題になるんですが、
ググるとそんなにネタが見当たらないんですよね。
sqlplusとかで実行して実際に”早い”事例があるので、
その他環境面の問題なんだろうとかいう話になり、
上に挙げたような簡易プログラム作って検証しても
結局「よくわからん」にたどり着くことが多いです。
この手の問題で調べると、
「フェッチサイズが異様に小さくて
検索結果の走査に無駄に時間かかってるのでは?」
という掲示板の回答を見かけたりします。
つまり実際にSQLを発行する⑦はsqlplusで実際に早かったときと同じスピードで終わるけど
そのあとのフェッチサイズが小さいから⑧のループで時間がかかる、
全体としてかえってくるまで遅く見える…
ということですね。
フェッチサイズは
rs.setFetchSize(1000);
で変更できます(やるとしたら⑦の後~⑧の直前)
ただ、確かデフォルト400だったはずなので
10万件超えるくらいのばかでかい検索結果じゃなければ
大体問題にならないような気もします。
下手にフェッチサイズ広げるとメモリ食いますしね。
「SQL単体だと早いけどJDBCから実行すると遅い」というのは
・サーバ上で実行するsqlplusは専用サーバ接続だから
・JDBCから発行するときはバインド変数を使っててそれで実行計画が変わってるから
・キャッシュじゃねーのか
…等等の疑問がいろいろあがりましたが
なんだかよくわらからないうちに「なんだかよくわからない」で片づけられてしまってます。
個人的にも気持ち悪いんですけどね。
なんでこーゆーこと起きるんですかね。