データベース接続

「データベース接続」の編集履歴(バックアップ)一覧はこちら

データベース接続」(2009/03/10 (火) 00:13:34) の最新版変更点

追加された行は緑色になります。

削除された行は赤色になります。

*&bold(){JDBCドライバの取得(MySQL用)} ※2009.03.01時点でのバージョンは5.1.7 以下の順でダウンロードする。 +ここにアクセス http://dev.mysql.com/downloads/ +Drivers and ConnectorsのMySQL Connector/J — for connecting to MySQL from Javaの「MySQL Connector/J 5.1」 +Source and Binaries (zip)の「Pick a mirror」 +New Usersの「Proceed」 +画面下部の「No thanks, just take me to the downloads!」 +好きなミラーサイトの「HTTP」 +適当な場所にダウンロード -インストール +ダウンロードしたファイルを解凍(mysql-connector-java-5.1.7.zip) +解凍したフォルダ内のmysql-connector-java-5.1.7-bin.jarをTomcatをインストールしたフォルダ\common\lib\にコピーする。 *&bold(){JDBCドライバのロード} MySQLの場合は次のように行う。 try { Class.forName("com.mysql.jdbc.Driver").newInstance(); }catch (ClassNotFoundException e){ }catch (Exception e){ } |URL|http://localhost:8080/database/databasetest| |アプリケーション配置場所|c:\servlet-sample\database\| |web.xmlファイル|c:\servlet-sample\database\WEB-INF\web.xml| |コンテキストファイル|C:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\Catalina\localhost\database.xml| *&bold(){データベースへの接続と切断} データベースへの接続を確立するには「DriverManager」クラスで用意されている"getConnection"メソッドを使う。 引数には接続するデータベースを表すURLと接続用のユーザー名とパスワードを指定する。 MySQLの場合、URLの形式は次のようになる。 jdbc:mysql://(サーバ名)/(データベース名) 例えばローカルホストにある「jdbctestdb」というデータベースに接続する場合は次のようになる。 jdbc:mysql://localhost/jdbctestdb 実際の使用例 Connection conn = null; String url = "jdbc:mysql://localhost/jdbctestdb"; String user = "testuser"; String password = "testpass"; try{ conn = DriverManager.getConnection(url, user, password); // データベースに対する処理 }catch (SQLException e){ } -データベースの切断 いったん接続した後に切断する場合には、接続の際に取得したConnectionインターフェースのオブジェクトに対して、"close"メソッドを使う。 "close"メソッドは何か問題が発生した際に忘れずに行うためにも、次のように"finally"節を使って記述する。 Connection conn = null; String url = "jdbc:mysql://localhost/jdbctestdb"; String user = "testuser"; String password = "testpass"; try{ conn = DriverManager.getConnection(url, user, password); // データベースに対する処理 }catch (SQLException e){ // 例外処理 }finally{ try{ if (conn != null){ conn.close(); } }catch (SQLException e){ // 例外処理 } } *&bold(){データベースの用意} データベース名は「jdbctestdb」とする。 +MySQLへ接続する: mysql -u root -p +パスワード応答 +データベースを作成する: create database jdbctestdb; +テスト用データベースに接続する: use jdbctestdb +テーブルを作成する: create table kabukatable(code int, company varchar(32), primary key(code) ); +ユーザの追加、権限設定: grant select,insert,update,delete on jdbctestdb.* to 'testuser'@'localhost' identified by 'testpass'; +データを追加する: 下記参照 +データを確認する: select * from kabukatable; &u(){データを追加する} ※コマンドプロンプトからINSERTしようとした場合、「ERROR 1366 (HY000): Incorrect string value: '\x83r\x83b\x83N...' for column 'com pany' at row 1」というエラーが発生し追加できない。これはどうやらMySQLインストール時に文字コードをutf-8にしたからの模様。正しい対処かどうかはわからないが、以下のSETコマンドを実行することでINSERTができるようになる。別セッションでSELECTしたりする場合は、毎回このSETを実行しないと文字化けする。 SET character_set_client = sjis; SET character_set_connection = utf8; SET character_set_results = sjis; insert into kabukatable values (3048,'ビックカメラ'), (4689,'ヤフー'), (4755,'RAKUTEN'), (9984,'SoftBank'); *&bold(){データベース接続テスト} |URL|http://localhost:8080/database/databasetest1| *&bold(){データの取得(SELECT)} -ステートメントを作成する Connection」インターフェースで定義されている"createStatement"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); -問い合わせの実行 「Statement」インターフェースで用意されている"executeQuery"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "SELECT * FROM kabukatable"; ResultSet rs = stmt.executeQuery(sql); -結果の取得 カーソルを動かすには「ResultSet」インターフェースで定義されている"next"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "SELECT * FROM kabukatable"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ /* 行からデータを取得 */ int code = rs.getInt("code"); String company = rs.getString("company"); } データ型毎の値取得メソッド一覧(一部) boolean getBoolean(String columnName) byte getByte(String columnName) Date getDate(String columnName) double getDouble(String columnName) int getInt(String columnName) long getLong(String columnName) Timestamp getTimestamp(String columnName) -リソースの開放 使わなくなった「ResultSet」オブジェクトは"close"メソッドを使ってリソースを開放する。 また、「Statement」オブジェクトもに"close"メソッドを使ってリソースを開放する。 rs.close(); stmt.close(); |URL|http://localhost:8080/database/databasetest2| *&bold(){データの更新(UPDATE)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "update kabukatable set company='楽天(株)' where code = 4755"; int num = stmt.executeUpdate(sql); |URL|http://localhost:8080/database/databasetest3| *&bold(){データの追加(INSERT)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "insert into kabukatable (code, company) values (2491, 'バリューコマース')"; int num = stmt.executeUpdate(sql); *&bold(){データの削除(DELETE)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "delete from kabukatable where id = 4755"; int num = stmt.executeUpdate(sql); *&bold(){インクルード(include)} 例えば、サーブレットAが呼ばれ、レスポンスに対して出力をしている途中でサーブレットBをインクルードしたとする。そうするといったんサーブレットBへ処理が移った後でサーブレットBの処理が終わったら呼び出し元のサーブレットAへ処理が戻り、残りの処理を行う。 例えばこのWebアプリケーションのパスが「/dispatch」でインクルードしたいサーブレットが「/dispatch/includetest」だった場合は次のようになる。 String disp = "/includetest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.include(request, response); |URL|http://localhost:8080/dispatch/dispatchtest| |アプリケーション配置場所|c:\servlet-sample\dispatch\| |web.xmlファイル|c:\servlet-sample\dispatch\WEB-INF\web.xml| |コンテキストファイル|C:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\Catalina\localhost\dispatch.xml| *&bold(){フォワード(forward)} インクルードと似ているがフォワードの場合は処理をフォワード先のサーブレットに移すため、呼び出し元のサーブレットには処理は戻って来ない。また呼び出し元の方ではレスポンスに対する出力も行えない。その為、呼び出し元の方で何らかの処理を行った上で、処理をフォワード先のサーブレットに完全に移す場合に利用する。 フォワードは、元のサーブレットへ送られてきたパラメータなども含めてフォワード先のサーブレットへそのままフォワードする。その為、クライアントからはサーブレット内部でフォワードされたことに気が付かないまま、フォワード先のサーブレットからの出力を受け取る。 String disp = "/forwardtest"; RequestDispatcher dispatch = request.getRequestDispatcher(disp); dispatch.forward(request, response); *&bold(){リクエストへの属性追加} フォワードなどを行う際に、フォワード先に何か別の情報を合わせて渡すことができる。クライアントから送られてきたリクエストをフォワード先に渡す前に、リクエストに属性を追加することで実現する。 呼び出し元:setAttributeメソッド request.setAttribute("hantei", "Out"); 呼び出し先:getAttributeメソッド String hantei = (String)request.getAttribute("hantei"); *&bold(){リダイレクト(redirect)} リダイレクトは他のサーブレットやHTMLファイルに処理を移す。フォワードと似ているが、フォワードはサーバ内で次のサーブレットなどへ処理を移すが、リダイレクトの場合はクライアントに対してリダイレクト先のサーブレットなどを見に行くように指示を出すだけ。その為、クライアント側でも処理が別のページ移ったことを認識できる。 例えば何かの処理をしてエラーだった場合にはエラーページへ飛ことや、データベースの処理だけをするサーブレットを呼び出した後に処理が終わったらサーブレットでは何も出力を行わずに特定のページへ飛ばすなどに使う。リダイレクトの場合には、別のサーバにあるURLへ飛ばすことも可能(フォワードの場合は同一サーバ内しか行えない)。 String url = "/dispatch/redirecttest"; response.sendRedirect(url);
*&bold(){JDBCドライバの取得(MySQL用)} ※2009.03.01時点でのバージョンは5.1.7 以下の順でダウンロードする。 +ここにアクセス http://dev.mysql.com/downloads/ +Drivers and ConnectorsのMySQL Connector/J — for connecting to MySQL from Javaの「MySQL Connector/J 5.1」 +Source and Binaries (zip)の「Pick a mirror」 +New Usersの「Proceed」 +画面下部の「No thanks, just take me to the downloads!」 +好きなミラーサイトの「HTTP」 +適当な場所にダウンロード -インストール +ダウンロードしたファイルを解凍(mysql-connector-java-5.1.7.zip) +解凍したフォルダ内のmysql-connector-java-5.1.7-bin.jarをTomcatをインストールしたフォルダ\common\lib\にコピーする。 *&bold(){JDBCドライバのロード} MySQLの場合は次のように行う。 try { Class.forName("com.mysql.jdbc.Driver").newInstance(); }catch (ClassNotFoundException e){ }catch (Exception e){ } |URL|http://localhost:8080/database/databasetest| |アプリケーション配置場所|c:\servlet-sample\database\| |web.xmlファイル|c:\servlet-sample\database\WEB-INF\web.xml| |コンテキストファイル|C:\Program Files\Apache Software Foundation\Tomcat 5.5\conf\Catalina\localhost\database.xml| *&bold(){データベースへの接続と切断} データベースへの接続を確立するには「DriverManager」クラスで用意されている"getConnection"メソッドを使う。 引数には接続するデータベースを表すURLと接続用のユーザー名とパスワードを指定する。 MySQLの場合、URLの形式は次のようになる。 jdbc:mysql://(サーバ名)/(データベース名) 例えばローカルホストにある「jdbctestdb」というデータベースに接続する場合は次のようになる。 jdbc:mysql://localhost/jdbctestdb 実際の使用例 Connection conn = null; String url = "jdbc:mysql://localhost/jdbctestdb"; String user = "testuser"; String password = "testpass"; try{ conn = DriverManager.getConnection(url, user, password); // データベースに対する処理 }catch (SQLException e){ } -データベースの切断 いったん接続した後に切断する場合には、接続の際に取得したConnectionインターフェースのオブジェクトに対して、"close"メソッドを使う。 "close"メソッドは何か問題が発生した際に忘れずに行うためにも、次のように"finally"節を使って記述する。 Connection conn = null; String url = "jdbc:mysql://localhost/jdbctestdb"; String user = "testuser"; String password = "testpass"; try{ conn = DriverManager.getConnection(url, user, password); // データベースに対する処理 }catch (SQLException e){ // 例外処理 }finally{ try{ if (conn != null){ conn.close(); } }catch (SQLException e){ // 例外処理 } } *&bold(){データベースの用意} データベース名は「jdbctestdb」とする。 +MySQLへ接続する: mysql -u root -p +パスワード応答 +データベースを作成する: create database jdbctestdb; +テスト用データベースに接続する: use jdbctestdb +テーブルを作成する: create table kabukatable(code int, company varchar(32), primary key(code) ); +ユーザの追加、権限設定: grant select,insert,update,delete on jdbctestdb.* to 'testuser'@'localhost' identified by 'testpass'; +データを追加する: 下記参照 +データを確認する: select * from kabukatable; &u(){データを追加する} ※コマンドプロンプトからINSERTしようとした場合、「ERROR 1366 (HY000): Incorrect string value: '\x83r\x83b\x83N...' for column 'com pany' at row 1」というエラーが発生し追加できない。これはどうやらMySQLインストール時に文字コードをutf-8にしたからの模様。正しい対処かどうかはわからないが、以下のSETコマンドを実行することでINSERTができるようになる。別セッションでSELECTしたりする場合は、毎回このSETを実行しないと文字化けする。 SET character_set_client = sjis; SET character_set_connection = utf8; SET character_set_results = sjis; insert into kabukatable values (3048,'ビックカメラ'), (4689,'ヤフー'), (4755,'RAKUTEN'), (9984,'SoftBank'); *&bold(){データベース接続テスト} |URL|http://localhost:8080/database/databasetest1| *&bold(){データの取得(SELECT)} -ステートメントを作成する Connection」インターフェースで定義されている"createStatement"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); -問い合わせの実行 「Statement」インターフェースで用意されている"executeQuery"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "SELECT * FROM kabukatable"; ResultSet rs = stmt.executeQuery(sql); -結果の取得 カーソルを動かすには「ResultSet」インターフェースで定義されている"next"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "SELECT * FROM kabukatable"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ /* 行からデータを取得 */ int code = rs.getInt("code"); String company = rs.getString("company"); } データ型毎の値取得メソッド一覧(一部) boolean getBoolean(String columnName) byte getByte(String columnName) Date getDate(String columnName) double getDouble(String columnName) int getInt(String columnName) long getLong(String columnName) Timestamp getTimestamp(String columnName) -リソースの開放 使わなくなった「ResultSet」オブジェクトは"close"メソッドを使ってリソースを開放する。 また、「Statement」オブジェクトもに"close"メソッドを使ってリソースを開放する。 rs.close(); stmt.close(); |URL|http://localhost:8080/database/databasetest2| *&bold(){データの更新(UPDATE)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "update kabukatable set company='楽天(株)' where code = 4755"; int num = stmt.executeUpdate(sql); |URL|http://localhost:8080/database/databasetest3| *&bold(){データの追加(INSERT)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "insert into kabukatable (code, company) values (2491, 'バリューコマース')"; int num = stmt.executeUpdate(sql); *&bold(){データの削除(DELETE)} 「Statement」インターフェースで用意されている"executeUpdate"メソッドを使う。 conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); String sql = "delete from kabukatable where id = 4755"; int num = stmt.executeUpdate(sql); *&bold(){prepareStatementの使用} 「Connection」インターフェースで定義されている"prepareStatement"メソッドを使う。 パラメータとして後から指定する部分には、実際の値を記述する替わりに「?」を記述したSQL文を作成し、そのSQLを元にプリペアドステートメントを作成する。 String sql = "insert into kabukatable (code, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); この例では実際に挿入する値を記述箇所に「?」を使っている。2箇所使っているので、後からパラメータを2つ指定する必要がある。 -パラメータへ値の設定 「PreparedStatement」インターフェースで用意されている「setInt」メソッドを使う。 パラメータの数だけメソッドを実行する。パラメータはSQL文中に記述された「?」を先頭から順番に1,2,3、・・・と順番に番号が割り当てられる。1番目のメソッドにはパラメータの番号を指定し、2番目の引数にパラメータに設定したい値を記述する。 String sql = "insert into kabukatable (code, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 4755); pstmt.setString(2, "楽天(株)"); パラメータに値を設定するには設定する値のデータ型毎に別々のメソッドが用意されてる。(一部) |メソッド|説明| |void setString(int parameterIndex, String x)|String 値に設定します。| |void setInt(int parameterIndex, int x)|int 値に設定します。| |void setLong(int parameterIndex, long x)|long 値に設定します。| |void setByte(int parameterIndex, byte x)|バイト配列に設定します。| |void setFloat(int parameterIndex, float x)|float 値に設定します。| |void setDouble(int parameterIndex, double x)|double 値に設定します。| |void setDate(int parameterIndex, Date x)|java.sql.Date 値に設定します。| |void setTime(int parameterIndex, Time x)|java.sql.Time 値に設定します。| |void setBoolean(int parameterIndex, boolean x)|boolean 値に設定します。| |void setTimestamp(int parameterIndex, Timestamp x)|java.sql.Timestamp 値に設定します。| -プリペアドステートメントの実行 「PreparedStatement」インターフェースにはSELECTなどのクエリーの結果を取得する場合に使う「executeQuery」メソッドと、INSERTやUPDATEなどの結果が返されない場合に使う「executeUpdate」メソッドがある。この使い方は「Statement」の場合と同じ。 conn = DriverManager.getConnection(url, user, password); String sql = "insert into kabukatable (code, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, 4755); pstmt.setString(2, "楽天(株)"); int num = pstmt.executeUpdate(); -パラメータのクリア プリペアドステートメントを複数回続けて実行する場合、値が変更されないパラメータについては改めて設定する必要はない。 次の例では1番目のパラメータは変更が無く、2回目に実行する時には2番目のパラメータだけを設定する。 String sql = "insert into kabukatable (basho, company) values (?, ?)"; PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setInt(1, "東証"); pstmt.setString(2, "ドコモ"); int num = pstmt.executeUpdate(); pstmt.setString(2, "KDDI"); num = pstmt.executeUpdate(); 現在設定されているパラメータを全て一度クリアしたい場合には「PreparedStatement」インターフェースで用意されている「clearParameters」メソッドを使う。 |URL|http://localhost:8080/database/databasetest6|

表示オプション

横に並べて表示:
変化行の前後のみ表示: