Java SE7 Gold 取得を目指して (13)


Java SE7 Gold をとりたい…!

本日は第13回目です。
JDBCについての章です。

今日のこぼれ話

こぼれている場合じゃない…! JDBCは盛りだくさんです。

本日知ったこと(10章)

  • JDBCの使い方(以下の順で流れる)

    1. データベースの指定
      • String url = "jdbc:mysql(subprotocol)://localhost/mydb(subname)";
      • デフォルトポートは 3306
    2. データベースとの接続
      • Connection con = DriverManager.getConnection(url, "username", "password");
      • JDBC4.0より Class.forName() によるドライバのロードが不要に(CLASSPATHに含まれていれば自動でロードする)
    3. ステートメントの取得
      • Statement st = con.createStatement();
    4. SQL実行
      • ResultSet rs = st.executeQuery("SELECT * FROM users");
    5. 結果の取得
      • rs.next()
      • 初期状態でカーソルは1行目の前(next()なしでデータを読もうとすると例外が出る)
      • getXXX(列番号|列名)(XXXはJavaの型名) でデータを取り出す(最初の列番号は1)
    6. リソースの解放
  • SQLステートメント

    • Statementインタフェース
    メソッド 説明
    ResultSet executeQuery(String sql) SQLを実行する
    結果が空でもnullは返さない
    int executeUpdate(String sql) SQLデータ操作言語文(UPDATE,INSERT,DELETE...)を実行する
    boolean execute(String sql) 実行結果がResultSetの場合はtrue、更新行数がないか結果がない場合はfalseを返す
    ResultSet getResultSet() 現在の結果であるResultSetを返す
    結果がカウントか結果がない場合はnull
    • PreparedStatement
    PreparedStatement st = con.preparedStatement("INSERT INTO users VALUES(?, ?, ?)");
    st.setInt(1, id); // 1つ目の?へidを設定
    st.setInt(2, age); // 2つ目の?へageを設定
    st.setString(3, name); // 3つ目の?へnameを設定
    
    • CallableStatement
    • ストアドプロシージャの呼び出しに使う
    CallableStatement st = con.prepareCall("{ call myprocedure (?, ?)}");
    st.setInt(1, 1000); // 1つ目の?へ入力パラメータを設定
    st.registarOutParameter(2, java.sql.Types.BIGINT); // 2つ目の?へ出力パラメータを設定
    st.execute();
    int result = st.getInt(2); // 結果(出力パラメータ)の取得
    
  • メタデータ

    • DatabaseMetaData
      • JDBCドライバ名やバージョン名などデータベースに関するメタデータを取得する
    • ResultSetMetaData
      • 列の型やResultSetに何行含まれているかなどResultSetに関するメタデータを取得する
  • ResultSet拡張

    • ステートメント取得時にResultSetを切り替えられる
    定数名 モード/タイプ
    CONCUR_READ_ONLY 更新できないResultSetオブジェクトの並行処理モード
    CONCUR_UPDATABLE 更新可能なResultSetオブジェクトの並行処理モード
    TYPE_FORWARD_ONLY カーソルは順方向にしか移動しない
    TYPE_SCROLL_INSENSITIVE スクロール可能
    データベースへの変更は反映しない
    TYPE_SCROLL_SENSITIVE スクロール可能
    データベースへの変更を反映する
    • データの挿入/更新
      • updateXXX(int columnIndex, XXX x)(XXXはString,intなど) で更新
      /* 行の挿入 */
      rs.moveToInsertRow(); // 挿入行へ移動
      rs.updateString(1, 100); // 値更新
      rs.updateString(2, "name");
      rs.insertRow(); // 行の挿入
    
  • トランザクション

    • con.setAutoCommit(false) で自動コミットオフ
    • con.setTransactionIsolation(int level) で分離レベルの設定
    定数名 ダーティーリード 反復不能リード ファントムリード
    TRANSACTION_NONE - - -
    TRANSACTION_READ_UNCOMMITTED 許可 許可 許可
    TRANSACTION_READ_COMMITTED 抑制 許可 許可
    TRANSACTION_REPEATABLE_READ 抑制 抑制 許可
    TRANSACTION_SERIALIZABLE 抑制 抑制 抑制
  • RowSet

    • DBへの問い合わせ結果をカプセル化する
    • アプリケーション側で使用しやすいように機能が拡張されている
    • DisConnected RowSet(DBへの接続が保持されない) と Connected RowSet(DBへの接続が保持される) がある
    • DisConnected RowSetなら接続断(close)後でも結果を取得できる
    • RowSetProvider → RowSetFactory でRowSetを取得する(Java7から)
    RowSetFactory factory = RowSetProvider.newFactory();
    JdbcRowSet rowSet = factory.createJdbcRowSet(); // RowSetごとにcreateXXXX()が用意されている