Java 重複しているコードをクラスにまとめる。

前回までに作成したJavaのプログラムでは、データベースに接続する部分が、各ソースコードで重複しています。ソースコードをコピーペーストで作ると、何か変更があったときに、修正箇所が複数になり面倒です。

java-411.gif

そこでデータベースに接続する部分を、共通して使うクラスとしてまとめることにします。そうするとデータベースの変更や、パスワードの変更があったとしても1箇所の修正だけで済みます。

今後の利用を考えると、本当はパッケージとしてクラスをまとめたいところですが、クラスパスの指定などが複雑に感じると思うので、シンプルに同じフォルダ内に配置しました。今回は「同じコードをまとめる」ことに集中してください。


【1】sample100 フォルダをフォルダごとコピーして、sample101 フォルダを作ります。

java-403.gif


【2】今回は以下のようなファイル構成になりますので、余計なものは削除してください。SampleDb030.java は今回新しく作ります。

java-404.gif


【3】各ソースファイルを以下のように変更します。

*「\」はWindowsではエンマークのことです。

保存先 C:\java\sample101
ファイル名 SampleDb030.java

import java.sql.*;

class SampleDb030{
  static Connection getConnection() throws Exception {
    //JDBCドライバのロード
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    //各設定
    String url = "jdbc:odbc:SampleDB030";
    String user = "";
    String pass = "";
    //データベースに接続
    Connection con = DriverManager.getConnection(url,user,pass);
    return con;
  }
}



保存先 C:\java\sample101
ファイル名 PrefSelect.java

import java.sql.*;

class PrefSelect {
  public static void main(String args[]) {
    try {
      //データベースに接続
      Connection con = SampleDb030.getConnection();
      //ステートメントオブジェクトを作成
      Statement stmt = con.createStatement();

      //SQL文作成
      String mySql = "select * from T01Prefecture order by PREF_CD";
      //検索するSQL実行
      ResultSet rs = stmt.executeQuery(mySql);

      System.out.println();
      System.out.println("PREF_CD PREF_NAME");
      System.out.println("--------------------");

      //結果セットからデータを取り出す next()で次の行に移動
      while(rs.next()) {
        int prefCd = rs.getInt("PREF_CD");
        String prefName = rs.getString("PREF_NAME");
        System.out.print(prefCd + "\t");
        System.out.println(prefName + "\t");
      }

      System.out.println("--------------------");

      //オブジェクトを解放
      rs.close();
      stmt.close();
      con.close();

    } catch (Exception e) {
      System.out.println("例外発生:" + e );
    }
  }
}



保存先 C:\java\sample101
ファイル名 PrefInsert.java

import java.sql.*;
import java.io.*;

class PrefInsert {
  public static void main(String args[]) {
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      System.out.println("PREF_CD を入力してください。");
      String str = br.readLine();
      int prefCd = Integer.parseInt(str);

      System.out.println("PREF_NAME を入力してください。");
      String prefName = br.readLine() ;

      //データベースに接続
      Connection con = SampleDb030.getConnection();
      //ステートメントオブジェクトを作成
      Statement stmt = con.createStatement();

      //SQL文作成
      String mySql = "insert into T01Prefecture values(" + prefCd + ", '" + prefName + "')";
      System.out.println();
      System.out.println("SQL:" + mySql);

      //SQL実行
      int num = stmt.executeUpdate(mySql);
      System.out.println(num + "件のレコードを追加しました。");
      //オブジェクトを解放
      stmt.close();
      con.close();
    } catch (NumberFormatException e) {
      System.out.println("値を整数型に変換できませんでした。");
      System.out.println("例外発生:" + e );
    } catch (Exception e) {
      System.out.println("例外発生:" + e );
    }
  }
}



保存先 C:\java\sample101
ファイル名 PrefUpdate.java

import java.sql.*;
import java.io.*;

class PrefUpdate {
  public static void main(String args[]) {
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      System.out.println("更新する PREF_CD を入力してください。");
      String str = br.readLine();
      int prefCd = Integer.parseInt(str);

      System.out.println("新しい PREF_NAME を入力してください。");
      String prefName = br.readLine() ;

      //データベースに接続
      Connection con = SampleDb030.getConnection();
      //ステートメントオブジェクトを作成
      Statement stmt = con.createStatement();

      //SQL文作成
      String mySql = "update T01Prefecture set PREF_NAME = '" + prefName + "' where PREF_CD = " + prefCd;
      System.out.println();
      System.out.println("SQL:" + mySql);

      //SQL実行
      int num = stmt.executeUpdate(mySql);
      System.out.println(num + "件のレコードを更新しました。");
      //オブジェクトを解放
      stmt.close();
      con.close();

    } catch (NumberFormatException e) {
      System.out.println("値を整数型に変換できませんでした。");
      System.out.println("例外発生:" + e );
    } catch (Exception e) {
      System.out.println("例外発生:" + e );
    }
  }
}



保存先 C:\java\sample101
ファイル名 PrefDelete.java

import java.sql.*;
import java.io.*;

class PrefDelete {
  public static void main(String args[]) {
    try {
      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

      System.out.println("削除する PREF_CD を入力してください。");
      String str = br.readLine();
      int prefCd = Integer.parseInt(str);

      //データベースに接続
      Connection con = SampleDb030.getConnection();
      //ステートメントオブジェクトを作成
      Statement stmt = con.createStatement();

      //SQL文作成
      String mySql = "delete from T01Prefecture where PREF_CD = " + prefCd;
      System.out.println();
      System.out.println("SQL:" + mySql);

      //SQL実行
      int num = stmt.executeUpdate(mySql);
      System.out.println(num + "件のレコードを削除しました。");
      //オブジェクトを解放
      stmt.close();
      con.close();

    } catch (NumberFormatException e) {
      System.out.println("値を整数型に変換できませんでした。");
      System.out.println("例外発生:" + e );
    } catch (Exception e) {
      System.out.println("例外発生:" + e );
    }
  }
}



【4】コマンドプロンプトを起動して、カレントディレクトリを sample101 に切り替えます。

java-405.gif


【5】各ソースファイルを以下のようにコンパイルします。

javac PrefSelect.java
javac PrefInsert.java
javac PrefUpdate.java
javac PrefDelete.java

java-406.gif

*SampleDb030.java は他のソースコードから利用されています。自動でコンパイルされるので、コンパイルの必要はありません。


【6】コンパイルが終了したら、以下のようなファイル構成になります。

java-412.gif


前回までとプログラムの動きは変わらないことを確認しましょう。

【7】java PrefSelect と入力し、検索プログラムを実行します。

java-407.gif


【8】java PrefInsertt と入力し、追加プログラムを実行します。

java-408.gif


【9】java PrefUpdate と入力し、更新プログラムを実行します。

java-409.gif

【10】java PrefDelete と入力し、削除プログラムを実行します。

java-410.gif


【解説】

(1)データベースに接続する部分を SampleDb030 クラスとしてまとめました。このクラスの getConnection() メソッドを呼び出すと、データベースに接続し、戻り値として Connection を返します。これでデータベースの変更や、パスワードの変更があった場合はこのクラスだけの修正で済むようになりました。


(2)getConnection() メソッドに static 修飾子を付けたのは、わざわざインスタンスを生成しなくてもメソッドを呼び出せるようにするためです。
static Connection getConnection() throws Exception {

また throws Exception は例外が発生したときに、メソッドの呼び出し元に例外処理を任せるということです。そのため、getConnection() メソッドには try-catch文 を書いていません。もちろん throws を使わずに try-catch文 を書いてこのメソッド内で処理することもできます。


(3)利用側でデータベースに接続するときは、以下の1文で済むようになりました。
Connection con = SampleDb030.getConnection();

getConnection()は static を付けているのでクラスメソッドです。クラスメソッドは、 クラス名.メソッド名 の形で呼び出します。そして戻り値を Connection 型の変数で受け取っています。


(4)実はまだステートメントオブジェクトを作成する部分が重複しています。
Statement stmt = con.createStatement();

メソッドの戻り値を Statement にすると重複しないように書けるのですが、Connectionオブジェクトには便利なメソッドが用意されているので、わざと Connection を戻り値にしました。

con.close() やトランザクション機能を利用するためのメソッドを使いたい場合に、Connectiont を戻り値にしていたほうが何かと便利だからです。


スポンサードリンク

スポンサードリンク






Java初心者入門講座TOPへ