Javaからデータベースへ接続するには、JDBC(Java DataBase Conectivity)というAPIクラス(Java SEに元々入っているクラスライブラリ)と、別途でJDBCドライバをインストールする必要がありました。
使用するデータベースがMySQLの場合だと、C:¥Program Files (x86)¥MySQL¥Connector.J 5.1¥mysql-connector-java-5.1.41-bin.jarのファイルがJDBCドライバになります。
JDBCドライバAPIとJDBCドライバについては、JDBCドライバの開発者が考慮することであるらしく、Javaでプログラムするときに考える必要はないようです。
JDBCドライバの種類
全部で4つのタイプが存在するようですが、専ら「タイプ4」 が利用されているようです。
タイプ2. ネイティブAPI
タイプ3. ネットプロトコル
タイプ4. ネイティブプロトコル
タイプを確認してみます。
Eclipseの「パースペクティブ」を「DBviewer」 に切り替えて、「DBツリー・ビュー」の『DBViewerPlugin』の上で右クリックし、「登録(A)」を選択。
「登録済みDriverから選択する(C)」を選択し、MySQLのJDBCドライバを選択します。
「次へ(N)>」を選択。
「JDBCタイプ(D):」に「Type4」「Type2」の2つが選択できることが分かりました。
確認できたので「キャンセル」をクリックします。 「パースペクティブ」も「Java」に戻しておきます。
JavaプロジェクトでMySQL接続
Eclipseで、「ファイル」>「新規」 >「Javaプロジェクト」
「プロジェクト名(P):」を入力し、「次へ(N)>」をクリック。
「完了(F)」をクリック。
続いて、作成したプロジェクトでJDBCドライバを利用できるようにします。
作成された「プロジェクト名」の上で右クリックし、「ビルド・パス(B)」>「ビルド・パスの構成(C)...」を選択。
「ライブラリー(L)」タグを選択した状態で、「外部JARの追加(X)...」を選択し、MySQLのJDBCドライバを選択します。
JDBCドライバが追加されたら、「OK」を選択。
「パッケージ・エクスプローラー」に「参照ライブラリー」>「mysql-connector-java-5.1.41-bin.jar」が追加されていればOK。
続いて「パッケージ」を作成。
「ファイル」>「新規」>「パッケージ」を選択。
「名前(M):」を入力し「完了(F)」 を選択。
続いて、「クラス」の作成。
作成したパッケージ上で右クリックし、「新規(W)」>「クラス」を選択。
「名前(M):」を入力し、「どのメソッド・スタブを作成ますか?」で、「public static void main(String[] args)(V)」にチェックをし、「完了(F)」をクリック。
SelectExsample.javaが作成されました。
データベースに接続していくためのコードを記述していきます。使用するデータベースは前回作成した、sampledbを使い、テーブルは、employeesを利用していきます。
package mysqlExample; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; public class SelectExsample { public static void main(String[] args) { // データベース接続のための情報 String url = "jdbc:mysql://localhost:3306/sampledb?useSSL=false"; String user = "root"; String password = "root"; int rowCount = 0; // try-with-resouces文でデータベースに接続 // SQL文を実行するためのStatementオブジェクトも生成 try(Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement() ) { // SQL文(SELECT文)を生成 String sql = "SELECT * FROM employees"; // SQL文を実行 ResultSet res = stmt.executeQuery(sql); // テーブルの列数とか取得するためのオブジェクト ResultSetMetaData rsmd = res.getMetaData(); // テーブルの列数 int columnCount = rsmd.getColumnCount(); // カラム名格納用 String[] colName = new String[columnCount]; // 行数を取得できるメソッドがないらしいので苦肉の策 res.last(); rowCount = res.getRow(); res.beforeFirst(); // 行数が取得できたので配列生成 String[] dbObject = new String[rowCount]; // SELECT文が実行されたか判定用の変数 int resCount = 0; // 文字列連結用 StringBuilder br = new StringBuilder(); // 行数でループ while(res.next()) { // 列数だけループ for(int columnIndex = 1; columnIndex <= columnCount; columnIndex++){ if(resCount == 0) { // カラム名 colName[columnIndex -1] = rsmd.getColumnName(columnIndex); } // データベースからの値を、String型にして文字列連結 br.append(colName[columnIndex -1]); br.append("="); br.append(res.getObject(columnIndex).toString()); // 行の最後の列かどうか if(columnIndex != columnCount) { br.append(", "); // 最後の列なら、改行 } else { br.append("\n"); } } // データベースの1行分を格納 dbObject[resCount] = br.toString(); // StringBuilderオブジェクトの中身を空にする br.setLength(0); // ResultSetを次の行へ resCount++; } // SELECT文が実行されていれば、 if(resCount != 0) { for(int i = 0; i < dbObject.length; i++) { System.out.print(dbObject[i]); } } } catch(SQLException e) { e.printStackTrace(); System.out.println("データベース接続かSQLの実行で異常が発生しました。"); } catch(Exception e) { } } }
いまいちデータベースから取得した値の保存の仕方が分からない感じですが、Mapを使うやり方が上手くいかずでした。
⇩ 下記サイトのようにスマートに記述したかったのですが
・【JAVA】DB取得結果分をHashMapを使いListに格納する - 高卒プログラマの日常
演習課題も解き方がなかなか思いつかない今日この頃です。
package mysqlEmployees; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class InsertEmployee { public static void main(String[] args) { // String url = "jdbc:mysql://localhost:3306/sampledb?useSSL=false"; String user = "root"; String password = "root"; String result = ""; String message = ""; try(Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); PreparedStatement pstmt = conn.prepareStatement("INSERT INTO employees VALUES(?, ?, ?, ? )");) { if(args.length != 4) { throw new ArrayIndexOutOfBoundsException(); } // 入力値 String input_code = args[0]; String input_name = args[1]; String input_age = args[2]; String input_section = args[3]; ResultSet res = stmt.executeQuery("SELECT * FROM employees WHERE code = " + input_code); int recordCount = 0; // SELECTした結果をループ while(res.next()) { recordCount++; } // 既に従業員コードが存在する場合、 if(recordCount != 0) { message = "を挿入できません。"; // 従業員コードが存在しない場合、 } else { message = "が挿入されました。"; pstmt.setString(1, input_code); pstmt.setString(2, input_name); pstmt.setInt(3, Integer.parseInt(input_age)); pstmt.setString(4, input_section); // prepareStatement(INSERT文)を実行 int count = pstmt.executeUpdate(); } // 処理結果 result += "CODE :" + input_code + "\n" + "NAME :" + input_name + "\n" + "AGE :" + input_age + "\n" + "SECTION :" + input_section; System.out.print("処理結果: 以下のレコード" + message + "\n"); System.out.println(result); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("引数の数が違います。<従業員コード><名前><年齢><部署>です。"); } catch (SQLException e) { // } catch (Exception e) { } } }
package mysqlEmployees; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class UpdateEmployee { public static void main(String[] args) { // String url = "jdbc:mysql://localhost:3306/sampledb?useSSL=false"; String user = "root"; String password = "root"; String message = ""; // try(Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); PreparedStatement pstmt = conn.prepareStatement("UPDATE employees SET code = ?, section = ?;")) { // コマンドラインの引数チェック if(args.length != 2) { throw new ArrayIndexOutOfBoundsException(); } String input_code = args[0]; String input_section = args[1]; ResultSet res = stmt.executeQuery("SELECT code FROM employees WHERE code = " + input_code); int resCount = 0; while(res.next()) { resCount++; } // 従業員コードが存在した場合、 if(resCount != 0) { pstmt.setString(1, input_code); pstmt.setString(2, input_section); message = "しました。"; // prepareStatement(UPDATE文)を実行 int count = pstmt.executeUpdate(); // 従業員コードが存在しない場合 } else { message = "できませんでした。"; } System.out.println("次のレコードを更新" + message + "CODE:" + input_code + " ==> SECTION:" + input_section); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("引数が違います。<従業員コード><部署コード>です。"); } catch(SQLException e) { // System.out.println("prepareStatementの実行に失敗しました。"); } catch(Exception e) { } } }
package mysqlEmployees; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class DeleteEmployee { public static void main(String[] args) { // String url ="jdbc:mysql://localhost:3306/sampledb?useSSL=false"; String user = "root"; String password = "root"; String message = ""; try(Connection conn = DriverManager.getConnection(url, user, password); Statement stmt = conn.createStatement(); PreparedStatement pstmt = conn.prepareStatement("DELETE FROM employees WHERE code = ?")) { if(args.length != 1) { throw new ArrayIndexOutOfBoundsException(); } String input_code = args[0]; ResultSet res = stmt.executeQuery("SELECT code FROM employees WHERE code = " + input_code); int resCount = 0; while(res.next()) { resCount++; } int count = 0; if(resCount != 0) { pstmt.setString(1, input_code); message = "しました。"; count = pstmt.executeUpdate(); } else { message = "できません。"; } System.out.println("次のレコードを削除" + message + "\t CODE:" + input_code); System.out.println(count + "件の変更"); } catch(ArrayIndexOutOfBoundsException e) { System.out.println("引数に従業員コードを指定してください。"); } catch(SQLException e) { System.out.println("データベース接続、またはprepareStatementの実行などに失敗しました。"); } catch(Exception e) { } } }
大人にも先生がいたって良い、って糸井重里さんが仰っていたような...。
同感です、館長。
今回はこのへんで。