広告

■□■□■□■□■□■□■□■□■□■□■□■□■□■□■
                      2011年02月06日

    Java総合講座 - 初心者から達人へのパスポート
                  2009年11月開講コース 038号

                                セルゲイ・ランダウ
 バックナンバー: http://www.flsi.co.jp/Java_text/
■□■□■□■□■□■□■□■□■□■□■□■□■□■□■


-------------------------------------------------------
・現在、このメールマガジンは以下の2部構成になっています。
[1] 当初からのコース:vol.xxx(xxxは番号)が振られています。
   これは現在、中級レベルになっています。
[2] 2009年11月開講コース:xxx号(xxxは番号)が振られています。
   これは現在、初心者向けのレベルになっています。
・このメールマガジンは、画面を最大化して見てください。
小さな画面で見ていると、不適切な位置で行が切れてしまう
など、問題を起すことがあります。
・このメールマガジンに掲載されているソース・コード及び
文章は特に断らない限り、すべて筆者が著作権を所有してい
ます。また、これらのソース・コードは学習用のためだけに
提供しているものです。
-------------------------------------------------------


========================================================
◆ 01.データベースを使用するアプリケーションの開発(続き)
========================================================

Departmentクラスのソース・コードから説明していきましょう。

Departmentクラスのソース・コードを下に再度提示します。
--------------------------------------------------------
package jp.co.flsi.lecture.entity;

public class Department {
   private int departmentNumber;
   private String departmentName;
   private String location;

   public void setDepartmentNumber(int departmentNumber) {
      this.departmentNumber = departmentNumber;
   }
  
   public int getDepartmentNumber() {
      return departmentNumber;
   }
  
   public void setDepartmentName(String departmentName) {
      this.departmentName = departmentName;
   }
  
   public String getDepartmentName() {
      return departmentName;
   }
  
   public void setLocation(String location) {
      this.location = location;
   }
  
   public String getLocation() {
      return location;
   }

}
--------------------------------------------------------

このクラスは企業の部門(部署)を表すものです。

まず、このクラスを入れるパッケージの名前には、1行目
--------------------------------------------------------
package jp.co.flsi.lecture.entity;
--------------------------------------------------------
の通り、entityという言葉を入れていますが、entityというのは
「実体」というような意味です。

ここで、entityという言葉について少し説明しておきます。

「エンティティー(entity)」はデータベース関連の専門書など
によく出てくる言葉ですが、「現実世界のオブジェクト」と同義
です。

たとえば、社員(employee)は一つのエンティティー(オブジェクト)
ですし、部門(department)は別のエンティティー(オブジェクト)
です。

データベースの場合は、一つのエンティティーは通常、データの
集合体として一つのテーブルに収められます。たとえば社員の情報
はEMPLOYEEというテーブルに収められ、部門の情報はDEPARTMENTと
いうテーブルに収められる、といった具合になります。

ここで、社員や部門はクラスであってインスタンスではないことに
注意してください。
つまりEMPLOYEEというテーブル名やDEPARTMENTというテーブル名は
クラスを表現するものです。

では、インスタンスはデータベース内では何によって表現されるか
というと、テーブルの中の一つの行が一つのインスタンスを表しま
す。

(なお、データベースの用語としては、オブジェクト指向とは異な
る意味でインスタンスという言葉を使うことがあるので注意してく
ださい。当メールマガジンではインスタンスという言葉はあくまで
オブジェクト指向の用語として使っています。)

詳しいことは、また後述するとして、ここではパッケージ名にentity
という言葉を含めることによって、現実世界のオブジェクトを記述す
るクラスが入っているパッケージであることをわかるようにしていま
す。


次に、4〜6行目
--------------------------------------------------------
   private int departmentNumber;
   private String departmentName;
   private String location;
--------------------------------------------------------
はそれぞれ部門オブジェクトの属性である部門コード(すなわち部門番号
=department number)、部門名(department name)、部門の所在地
(location)を表す属性変数(フィールド)です。

そして、8〜30行目
--------------------------------------------------------
   public void setDepartmentNumber(int departmentNumber) {
      this.departmentNumber = departmentNumber;
   }
  
   public int getDepartmentNumber() {
      return departmentNumber;
   }
  
   public void setDepartmentName(String departmentName) {
      this.departmentName = departmentName;
   }
  
   public String getDepartmentName() {
      return departmentName;
   }
  
   public void setLocation(String location) {
      this.location = location;
   }
  
   public String getLocation() {
      return location;
   }
--------------------------------------------------------
は、それぞれの属性変数に対するsetメソッド(setterメソッド)
およびgetメソッド(getterメソッド)を記述したものです。

setメソッドが属性にデータをセット(記憶)し、getメソッドが属性
のデータを取得(読み出し)するものであることは以前お話した通り
ですが、実際の部門のデータは以前作成したDEPARTMENTテーブルの中
に保存されています。


本来、プログラム内の通常のオブジェクトはプログラムの実行が終了
するとメモリー上から消えてしまいますから、オブジェクトの中のデータ
も消えてしまいます。

プログラムの終了後にもプログラムのデータを残しておくためには、
データベースや通常のファイルにデータを保存しておく必要がある
わけです。

そのために、現在作っているアプリケーションでもデータベースを
使用しているわけです。

そして、リレーショナル・データベースを使用する場合は、オブジェ
クトが持つデータすなわち属性の値をデータベースに保存したり、
あるいは逆にデータベースのデータをオブジェクトの属性の値として
取り込む操作をプログラム中に実装する必要があります。

この際には、オブジェクトの属性とデータベースのデータの間に対応
付けが必要になりますが、データベースのテーブルのカラムをオブジェ
クトの属性に対応するものとして扱うことができます。

たとえば、上のDepartmentクラスには以前作成したDEPARTMENTテーブル
が対応し、それぞれの属性とカラムの間には下記のような対応関係があ
ります(というよりも、このような対応関係ができるようにクラスや
テーブルを作ったのです)。

Departmentクラス
の属性
DEPARTMENTテーブル
のカラム
departmentNumber <--> DEPART_NUM
departmentName <--> DEPART_NAME
location <--> LOCATION

また、DEPARTMENTテーブルの一つ一つの行には、それぞれ異なる部門の
データがはいっていますから、それぞれ一つ一つの行が異なるインスタ
ンスを表現しているわけです。


こうして、Javaのオブジェクトとデータベースとの間に対応付けができる
わけです。

コンピューター関連の専門書では、この「対応付け」に対して「マッピング」
という言葉がよく使われます。


┌補足─────────────────────────┐
数学では一つの集合(set)の元(element=要素)から別の集合の
元(要素)への対応付けが明確に決まっているときに、この対応付け
のことを「写像」と言いますが、この「写像」のことを英語では
「mapping」といいます。(なお、詳しい正確な定義については数学
の本を参照してください。)

コンピューター関連の英語の専門書を読むと、よく「mapping」という
単語がなんの定義もなく使われていることがありますが、これは数学
用語の「写像」の意味です。
(ちなみに「map」は数学用語では「写像」もしくは「写像する」と
いう意味の動詞として使われる。)

英語圏のコンピューター技術者は学生時代に習った数学でこの用語
には慣れていますから、なんの説明もいらないわけです。

ところが残念ながら英語の専門書を翻訳する日本の翻訳者にはこの
単語の意味がわからない人が多いらしく、「mapping」を何の説明も
せずにそのまま「マッピング」というカタカナに置き換える習慣が
ついてしまったようです。

これでは、はじめてこの単語を見た人は「マッピングって何だ?」と
いうことになります。

というわけで、皆さんは専門書を読んで「マッピング」という単語を
見つけたら、「mapping(= 写像)」のことであることを思い出して
ください。


もっとも、こういった簡単な単語の多くは文脈から容易に意味が理解
できるのであまり問題にはならないのですが、注意していただきたい
ことは、翻訳された専門書には結構、誤訳や意味不明の文がたくさん
あるということです。

コンピューター関連の専門書を翻訳する人が専門知識を持っていない
ことも多いし、しかも最近では翻訳ソフトを使って機械的に自動翻訳
させる場面が増えているので、完璧な翻訳が難しいのです。

たとえば、金融関連のシステムに関する翻訳で「securities」を
「安全」と訳してあるものがあったのですが、これは「証券」の間
違いです。
このような誤訳があると、文章がなんとなく意味不明になるので、
専門家が読むとすぐに間違いに気づきますが、意味が理解できなく
て考え込んでしまう人もいます。

意味不明はまだしも、なかには意味が逆になっているような(たとえば
「xのときはyしない」と訳すべきところが「「xのときはyする」になっ
ているとか)ひどい文がでてくることもあります。こんなものを読んで
理解できないところをなんとか理解しようと努力するのは時間の無駄です。

理解できないならまだいいのですが、誤訳のまま理解できてしまって、
間違った知識が頭に定着してしまったりしたらもっと大変です。

というわけで、できれば、専門書は原書で読みたいものです。

また、現在のコンピューター関連の専門書は、最先端のものはほとんど
が英語で書かれていますから、最先端の技術者になるためには英語の
専門書を読む能力が不可欠です。

というわけで、英語はちゃんと勉強しておきましょうね。
もっとも、コンピューター関連の専門書の英語は平易なので、難解な
英文学書を読みこなすような高度な(?)英語力は必要ありません。

しかしながら、本に書いてあることや人から聞いたことをなんでも
鵜呑みにしない、という精神も大切です。
特にプログラミングに関することであれば、自分で直接プログラムを
書いて試験(実験)、あるいは確認することができるのですから、
重要なことは直接自分で確認するようにしましょう。
└───────────────────────────┘


では、次にDbManagerというクラスを見てみましょう。

ソース・コードを下記に再度提示します。
--------------------------------------------------------
package jp.co.flsi.lecture.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DbManager {
   protected static Connection conn = null;
   protected String driver = "org.h2.Driver";
   protected String url = "jdbc:h2:tcp://localhost/~/test";
   protected String dbUser = "sa";
   protected String dbPassword = "";

   protected void connect() throws java.sql.SQLException {
      try {
         if(conn == null || conn.isClosed()) {
            Class.forName(driver);
            conn = DriverManager.getConnection
                        (url, dbUser, dbPassword);
            conn.setAutoCommit(false);
         }
      } catch(ClassNotFoundException ex) {
         ex.printStackTrace();
      }
   }

   protected void disconnect() {
      try {
         conn.close();
      } catch(SQLException ex) {
         ex.printStackTrace();
      }
   }

}
--------------------------------------------------------
パッケージ名にdbという文字を含めているのは、データベース関係
のクラスを入れるパッケージなので、databaseの略のdbという文字列
を付けたものです。

このDbManagerというクラスは、データベースへの接続とその逆(接続が
不要になったときの後始末)をしているだけですね。

022号などで説明したプログラムでは、これらをmain()メソッドの中で
一挙にやっていましたが、ここでは接続はconnect()というメソッドで行い、
その逆はdisconnect()というメソッドで行うように、メソッドを振り分け
ています。

ここで、14行目に出てくる
--------------------------------------------------------
throws java.sql.SQLException
--------------------------------------------------------
というのは、「このconnect()というメソッドの中でSQLExceptionという
Exception(例外)が発生する可能性があるが、connect()メソッドの中で
は捕らえない(SQLExceptionに対するcatch文がない)ので、connect()メ
ソッドを呼び出す側で捕らえてくれ(catchしてくれ)」という意味を表
します。(実際にどこでどうcatchするのかは後述。)

その他のコードのほとんどの部分は022号あたりで説明済みのものです。


次にDEPARTMENTテーブルを処理するためのクラスとしてDepartmentDbManager
というクラスを用意していましたが、そのソース・コードを下に再度提示し
ます。
--------------------------------------------------------
package jp.co.flsi.lecture.db;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Vector;

import jp.co.flsi.lecture.entity.Department;

public class DepartmentDbManager extends DbManager {
   private Vector departmentList = new Vector();

   public Vector getDepartmentList() {
      return departmentList;
   }

   public void getAllData() {
      try {
        connect();
        Statement selectSql = conn.createStatement();
        ResultSet rs = selectSql.executeQuery("SELECT * FROM DEPARTMENT");
        while (rs.next()) {
            Department aDepartment = new Department();
            aDepartment.setDepartmentNumber(rs.getInt("DEPART_NUM"));
            aDepartment.setDepartmentName(rs.getString("DEPART_NAME"));
            aDepartment.setLocation(rs.getString("LOCATION"));
            getDepartmentList().addElement(aDepartment);
        }
        selectSql.close();
        disconnect();
      }
      catch (SQLException exception) {
        exception.printStackTrace();
      }
   }
  
}
--------------------------------------------------------

このクラスのgetAllData()メソッドでは、データベースのDEPARTMENTテーブル
の中のすべての行のデータを読み取って、それぞれDepartmentクラスのイン
スタンスの属性値として記憶させています。

この中では、java.utilパッケージのVectorというクラスを使っていますが、
Vectorは配列のような仕組みを提供するクラスです。

Departmentクラスのインスタンスが複数作られるので、複数個のオブジェクト
を記憶できる変数として配列を使いたいところですが、配列よりもVectorを
使ったほうが便利なので、ここではVectorを使用しています。

というのは、Vectorは配列と違って要素数が固定されないので、必要なとき
にいくらでも要素を追加することができるし、いらなくなったらどの要素で
も好きなときに削除することができるからです。

┌補足─────────────────────────┐
複数のオブジェクトを収めたオブジェクトをコレクション
(collection)と呼び、Vectorもコレクションの一種です。
コレクションは、言わばオブジェクトを入れる入れ物のような
イメージのオブジェクトです。
Vectorとほぼ同様に使用できるコレクションとしてArrayListと
いうクラスがあり、Vectorの代わりにArrayListを使ったほうが
パフォーマンス(処理性能)はいいのですが、ここでは古くから
(Javaが世に出た当初から)あるVectorを先に紹介し、ArrayList
はまた後の記事で紹介することにします。
└───────────────────────────┘

はい、ではソース・コードを説明していきます。

11行目の
--------------------------------------------------------
   private Vector departmentList = new Vector();
--------------------------------------------------------
ではVectorクラスのインスタンスを生成していますね。
このVectorはDepartmentクラスのインスタンスを複数入れるためのリストの
入れ物として使うつもりなので、departmentListという変数名にしています。

┌補足─────────────────────────┐
上記のインスタンス生成のコードの代わりに、コレクション
の中に収められるオブジェクトの型を<>の中に記述して
   private Vector<Department> departmentList = new Vector<Department>();
というような書き方をすることもできます。
このように型を<>の中にパラメーターとして指定できるものを
総称型(generic type)といいます。

総称型のコレクションでは、<>の中に型を記述しておけば、その
型に適合しないオブジェクトを入れようとしたときなど、その型
に違反するようなコードがあるとJavaコンパイラーがエラーとし
て知らせてくれるため、ソース・コードのバグを減らすことに
役立ちます。

しかし、上記のように<>のない宣言文(これをraw型と呼ぶこと
があります)の場合は、あらゆる型のオブジェクトがすべてこの
コレクションの中に入れられることになり、コンパイラーは特定
の型のチェックをしません。
└───────────────────────────┘

13〜15行目の
--------------------------------------------------------
   public Vector getDepartmentList() {
      return departmentList;
   }
--------------------------------------------------------
は、そのdepartmentListのgetメソッドです。setメソッドが用意されていな
いのは、11行目ですでにインスタンス生成されているのでsetする必要がない
からです。


続いて、17〜35行目のgetAllData()メソッドの部分
--------------------------------------------------------
public void getAllData() {
   try {
      connect();
      Statement selectSql = conn.createStatement();
      ResultSet rs = selectSql.executeQuery("SELECT * FROM DEPARTMENT");
      while (rs.next()) {
         Department aDepartment = new Department();
         aDepartment.setDepartmentNumber(rs.getInt("DEPART_NUM"));
         aDepartment.setDepartmentName(rs.getString("DEPART_NAME"));
         aDepartment.setLocation(rs.getString("LOCATION"));
         getDepartmentList().addElement(aDepartment);
      }
      selectSql.close();
      disconnect();
   }
   catch (SQLException exception) {
      exception.printStackTrace();
   }
}
--------------------------------------------------------
を見てみましょう。

このメソッドは、データベースのDEPARTMENTテーブルの中のすべて
の行のデータを読み取って、それぞれDepartmentクラスのインスタ
ンスの属性値として記憶させています。

まず19行目
--------------------------------------------------------
connect();
--------------------------------------------------------
は、自分のconnect()メソッドを呼び出して実行しています。

007号で説明したように、自分のメソッドを呼び出すときには
オブジェクトの指名は不要でしたね。

あるいは、明示的に指名したい場合は
this.connect();
というようにthisというキーワードを使えば自分のメソッドを
呼び出していることが明確になります。

ところで、connect()というメソッドはDepartmentDbManagerクラス
の中には定義されていませんね。
いったいどこに定義してあるのでしょうか。

Eclipseにソース・コードをすべて入力済みの人は、この20行目の
connect()の部分をクリックしてカーソルを入れておき、F3キーを
押してみてください。connect()メソッドの定義場所に飛んでくれ
ます。
(逆に以前のページに戻るにはAltキーを押しながら左向きのカーソ
ル・キー([←]キー)を押します。)

そうです。DbManagerクラスの中で定義されているのです。

DbManagerクラスはDepartmentDbManagerクラスのスーパークラス
でしたね。
(DepartmentDbManagerクラスのクラス定義の中にextends DbManager
という記述があります。)

このconnect()メソッドはスーパークラスのDbManagerから継承してい
るものであり、DepartmentDbManagerクラスの中では定義されていま
せん。

┌補足─────────────────────────┐
もしDbManagerとDepartmentDbManagerの両方にconnect()メソッドが
定義されている場合には、スーパークラス(DbManager)のconnect()
メソッドは継承されず、「connect();」あるいは「this.connect();」
という文では自分(DepartmentDbManager)のconnect()メソッドが呼
び出されることになります。
この場合に、スーパークラスのconnect()メソッドを呼び出したいとき
は「super.connect();」というようにsuper.をつけます。
たとえば

public class DbManager {
        ・
        ・
   protected void connect() throws java.sql.SQLException {
        ・
        ・
   }
}

public class DepartmentDbManager extends DbManager {
        ・
        ・
   protected void connect() throws java.sql.SQLException {
        ・
        ・
   }

   public void getAllData() {
      try {
         super.connect();
        ・
        ・
      }
      catch (SQLException exception) {
         exception.printStackTrace();
      }
   }

}

のように、connect()の呼び出し時にsuper.をつけてやるとスー
パークラス(つまりDbManager)のconnect()メソッドが呼び出さ
れます。
何もつけないか、あるいはthis.をつけると自分のconnect()メソッ
ドが呼び出されることになります。
└───────────────────────────┘


DbManagerクラスの14〜24行目
--------------------------------------------------------
protected void connect() throws java.sql.SQLException {
   try {
      if(conn == null || conn.isClosed()) {
         Class.forName(driver);
         conn = DriverManager.getConnection(url, dbUser, dbPassword);
         conn.setAutoCommit(false);
      }
   } catch(ClassNotFoundException ex) {
      ex.printStackTrace();
   }
}
--------------------------------------------------------
を見てください。

14行目にprotectedというキーワードが指定されていますが、005号
で簡単に説明したように、このprotectedは「一般には隠蔽し、同族内
でのみアクセス(使用)できる」ことを意味するキーワードです。

「同族内でのみアクセス(使用)できる」というのは、詳しくは
「同じオブジェクトの内部でアクセスするか、または、同じパッ
ケージ内の他のオブジェクトからアクセスするか、または、サブ
クラスのオブジェクトからアクセスする場合はアクセスでき、それ
以外のオブジェクトからアクセスする場合はアクセスできない
(一般には隠蔽されている)」という意味です。
(このprotectedというアクセス制御はいささかわかりにくいので、
別の機会にアクセス制御全体をまとめて詳しく説明いたします。)

というわけで、DepartmentDbManagerはこのDbManagerのconnect()メ
ソッドを使用することができます。

一方、このメソッドは部外者には使わせたくないからと言って、もし、
protectedの代わりにprivateを指定してしまうと、そのサブクラスで
さえ、そのメソッドにアクセスできなくなってしまいます。

サブクラスに使わせたい場合は、このようにprotectedを指定します。


このDbManagerのconnect()メソッドの中に、まだ説明していなかった
コードがあったので、この場で説明しておきましょう。

まず16行目
--------------------------------------------------------
if(conn == null || conn.isClosed()) {
--------------------------------------------------------
のif文はconn(Connection)が存在していない(null)か、または
close済み(isClosed())の場合には処理を実行することを意味し
ます。

connは8行目
--------------------------------------------------------
protected static Connection conn = null;
--------------------------------------------------------
で定義されていますが、初期値をnullにしていますね。
こうやっておくと、connの値がnullであれば、まだデータベースへ
の接続が行われていないことが明確になります。

一方、ConnectionのisClosed()メソッドは、Connectionのclose()メ
ソッドが呼ばれた後の状態であればtrueを返し、そうでなければfalse
を返します。
つまりcloseしたかどうかを教えてくれるメソッドです。

つまり、まだデータベースへの接続がされていないか、あるいは
接続がcloseされた後であればデータベースへの接続の操作を行い、
現在接続されている状態であれば接続の操作を行わないようにコー
ディングしてあるわけです。


データベースのテーブルからデータを取ってくるためには、その前に
データベースに接続しておかなければなりませんが、この接続の操作
はテーブルには依存しないので、個々のテーブルを処理するクラスが
担当する仕事ではありません(オブジェクト指向では役割分担を明確
にするのが鉄則です)。

そこで、個々のテーブルには依存しない、データベース関連の共通の
処理としてDbManagerクラスにconnect()メソッドを定義しています。


次に21〜23行目
--------------------------------------------------------
} catch(ClassNotFoundException ex) {
   ex.printStackTrace();
}
--------------------------------------------------------
ですが、catch文とExceptionのprintStackTrace()メソッドについては
既に(018号と022号で)説明済みですが、ClassNotFoundException
というのは初めて出てきたかと思います。

ClassNotFoundExceptionは文字通りクラスが見つからなかったときに発生
するException(例外)で、ここでは17行目
--------------------------------------------------------
Class.forName(driver);
--------------------------------------------------------
でJDBCドライバーのクラスをロードするときにそのクラスが見つからない
と発生します。
何というクラスかというと、9行目
--------------------------------------------------------
protected String driver = "org.h2.Driver";
--------------------------------------------------------
を見ると、org.h2.Driver、つまりorg.h2パッケージのDriverというクラス
をロードしようとしていることがわかりますね。

なお、SQLExceptionはcatchはしていませんが、代わりに14行目
--------------------------------------------------------
protected void connect() throws java.sql.SQLException {
--------------------------------------------------------
でSQLExceptionをthrowsしています。

この「throws」というキーワードは、
「当メソッドの中ではこのExceptionはcatchせず、このExceptionはそのまま
当メソッドの外に放り出します」
という意味を表します。

しかし、Exceptionはどこかで処理(catch)しなければなりません。
当アプリケーションでは、どこでcatchしているかというと、getAllData()メ
ソッドの中でcatchしています。

DepartmentDbManagerのgetAllData()メソッドの定義の中で、connect()メソッ
ドを呼び出しているところ(19行目)がtryのブロックに囲まれていることと、
そのブロックの下にcatch文でSQLExceptionを捕らえていること(32行目)を
確認してください。

このようにして、connect()メソッドが放り出したSQLExceptionをgetAllData()
メソッドの中で処理しています。


では、DepartmentDbManagerのgetAllData()メソッドの次の行を見てみましょう。

20行目
--------------------------------------------------------
Statement selectSql = conn.createStatement();
--------------------------------------------------------

この文の中のconnは、DepartmentDbManagerの中では定義されていません。
これもやはり、スーパークラスのDbManagerから継承したものです。

DbManagerの8行目
--------------------------------------------------------
protected static Connection conn = null;
--------------------------------------------------------
を再度見てみましょう。protectedが指定されていますので、サブクラスでも
アクセス(使用)できることがわかります。

ついでにstaticが指定されていることにも注意しましょう。

staticというキーワードが指定された変数はインスタンス変数ではなく、
クラス変数でしたね。これは、個々のインスタンスには関係なく、クラス
で共有される変数です。

これはデータベースへの接続を複数のオブジェクトで共有しようという意図
があるためにstaticを指定したものですが、詳しいことは後述します。

次の21行目
--------------------------------------------------------
ResultSet rs = selectSql.executeQuery("SELECT * FROM DEPARTMENT");
--------------------------------------------------------
は言うまでもなく、DEPARTMENTテーブルをすべて検索(取り出し)して、
その検索結果をrsという変数(ResultSet型のオブジェクトがはいる)に
代入している文です。

その次の「while (rs.next())」の働きについても、024号で説明した
とおりです。

その次の
--------------------------------------------------------
Department aDepartment = new Department();
--------------------------------------------------------
では、Departmentクラスのインスタンスを生成し、その次の
--------------------------------------------------------
aDepartment.setDepartmentNumber(rs.getInt("DEPART_NUM"));
aDepartment.setDepartmentName(rs.getString("DEPART_NAME"));
aDepartment.setLocation(rs.getString("LOCATION"));
--------------------------------------------------------
では、DEPARTMENTテーブルの各カラムの値をDepartmentのインスタン
スの対応する属性にセットしています。これも024号あたりの説明が
頭にはいっていれば理解できるはずです。

次の
--------------------------------------------------------
getDepartmentList().addElement(aDepartment);
--------------------------------------------------------
ではそのDepartmentのインスタンスをdepartmentList(Vectorの
インスタンス)に追加しています。

Vectorというのは配列のような働きをするクラスですが、配列と違っ
て、宣言時に要素数が固定されることなく、いつでも好きなときに
要素を追加したり削除したりできるのでしたね。

このaddElement(aDepartment)というメソッドは、Vectorのインスタ
ンスにaDepartmentを要素(element)として追加するメソッドです。
Vectorオブジェクト(インスタンス)はその記憶域にリスト(配列の
ようなものだが要素数が可変)を持っているのですが、このメソッド
では、引数に指定したオブジェクトがリストの最後に追加されます。
ただし、リストの中がまだ空っぽのときは、先頭に追加されることに
なります。

なお、getDepartmentList()というのはdepartmentListを取り出すた
めのメソッドでしたね。

ここでは、getDepartmentList()の代わりにdepartmentListと書いて
--------------------------------------------------------
departmentList.addElement(aDepartment);
--------------------------------------------------------
としても同じように作動しますが、getメソッドがある場合はgetメ
ソッドを使うべきです。
(もし、後にdepartmentListに対して何らかの仕様変更が行われたと
しても、その変更部分はgetメソッドのコードを修正することによって
吸収してしまうというのが鉄則であり、getメソッドを呼び出す側は
影響を受けずにすむからです。
それに対し、もしdepartmentListを直接呼び出している箇所があると、
その呼び出し箇所をすべて修正する必要が生じ、面倒になります。)

30行目
--------------------------------------------------------
disconnect();
--------------------------------------------------------
で呼び出しているdisconnect()というメソッドは、connect()と同じく
DbManagerのものです。

DbManagerの26行目〜32行目
--------------------------------------------------------
protected void disconnect() {
   try {
      conn.close();
   } catch(SQLException ex) {
      ex.printStackTrace();
   }
}
--------------------------------------------------------
を見ると(Exceptionの処理以外は)たんにConnectionのclose()メソッ
ドを呼び出しているだけだということがわかります。


以上でDepartmentDbManagerおよびDbManagerのソース・コードはすべて
理解できますね。



では、次にComboBoxModelOfDepartmentクラスの説明をしていきましょう。

(次回に続く)


では、また来週。



================================================
◆ 02.演習問題
================================================

DbManagerのconnect()メソッドには

throws java.sql.SQLException

が記述されているのに、disconnect()メソッドにはそれが無く、代わりに
disconnect()メソッドの内部でSQLExceptionがcatchされていますね。

これはなぜなのか考えてみて下さい。


では、また来週。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      http://www.flsi.co.jp/Java_text/
★このメールマガジンは
     「まぐまぐ(http://www.mag2.com)」
 を利用して発行しています。
★バックナンバーは
      http://www.flsi.co.jp/Java_text/
 にあります。
★このメールマガジンの登録/解除は下記Webページでできます。
      http://www.mag2.com/m/0000193915.html
★このメールマガジンへの質問は下記Webページにて受け付けて
 います。わからない所がありましたら、どしどしと質問をお寄
 せください。
      http://www.flsi.co.jp/Java_text/
┗━━━━━━━━━━━━━━━━━━━━━━━━━━━┛

Copyright (C) 2011 Future Lifestyle Inc. 不許無断複製