■■■■■■■■■■■■■■■■■■■■■■■■■■■■■
                      2009年04月12日

    Java総合講座 - 初心者から達人へのパスポート
                  vol.148

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


[このメールマガジンは、画面を最大化して見てください。]


========================================================
◆ 01.SOAPのアプリケーション(Webサービス)
========================================================


このRoomInfoDbManagerクラスのgetData()メソッドの引数の
capacity, minRate, maxRateは、それぞれ、検索対象とする部屋の
収容人数、料金(一人当たりの一泊料金)の最低限度額、最高限度額
を指定するものです。
なお、この最低限度額や最高限度額を省略するときは(int型では
無指定という訳にはいかないので)負の数を指定するものとし、
if文で処理してあります。
具体的には、

         if (maxRate > -1) {
            selectPs = conn.prepareStatement(selectCapaAndRateSql);
            selectPs.setInt(1, capacity);
            selectPs.setInt(2, minRate);
            selectPs.setInt(3, maxRate);
         }
         else if (minRate > -1) {
            selectPs = conn.prepareStatement(selectCapaAndMinRateSql);
            selectPs.setInt(1, capacity);
            selectPs.setInt(2, minRate);
         }
         else {
            selectPs = conn.prepareStatement(selectCapaSql);
            selectPs.setInt(1, capacity);
         }

というソース・コードによって処理しています。
本来ならば、もっと複雑な条件文(たとえば(maxRate > -1)かつ(minRate > -1)
の場合も振り分けて処理すべき)にするでしょうけれど、ここはたんなる
学習用のサンプルなのでソース・コードを単純化しています。

残りの部分は、解説しなくても理解できることと思います。



さて、このRoomInfoDbManagerクラスのメソッドを使えば、とりあえず部屋の
検索はできますが、その部屋が予約したい日に空いているかどうかはわかり
ません。

そこで、指定された日にその部屋が予約済みでないことを確認するためのプログラム
も作っておきましょう。
指定された日にその部屋が予約済みであるかどうかは、ROOMBOOKテーブルを検索
すればわかります。
というわけで、同じパッケージの中にRoomBookDbManagerというクラス名で下記のよう
な内容のクラスを作成してください。

--------------------------------------------------------
package jp.co.flsi.lecture.webservice.hotel.db;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.GregorianCalendar;
import java.util.Vector;

import org.apache.log4j.Logger;

public class RoomBookDbManager extends DbManager {
   private static final String selectRoomnumAndDateSql = "SELECT * FROM ROOMBOOK WHERE ROOMNUM = ? AND DATE = ?";
   private static Logger logger = Logger.getLogger(RoomBookDbManager.class);

   public static Vector<Integer> getBookedRoomNum(int roomNum, GregorianCalendar stayDate) throws HotelDbException {
      Vector<Integer> roomNumList = new Vector<Integer>();
      logger.info("Start ...............");
      try {
         PreparedStatement selectPs = null;
         ResultSet rs;
         selectPs = conn.prepareStatement(selectRoomnumAndDateSql);
         selectPs.setInt(1, roomNum);
         selectPs.setDate(2, new Date(stayDate.getTimeInMillis()));
         rs = selectPs.executeQuery();
         while (rs.next()) {
            roomNumList.add(rs.getInt("ROOMNUM"));
         }
         selectPs.close();
      }
      catch (SQLException e) {
         logger.error(e);
         throw new HotelDbException("Error: getBookedRoomNum() failed!", e);
      }
      finally {
         logger.info("End ...............");
      }
      return roomNumList;
   }

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

このgetBookedRoomNum()メソッドの引数のroomNum, stayDateは、それぞれ、
予約済みかどうかを検索したい部屋の部屋番号と宿泊予定日です。
このメソッドは、ROOMBOOKテーブルにアクセスして、指定された部屋番号と宿泊予定日
に対して該当するレコードがあるかどうか検索し、あればその部屋番号をVector型の
リストに追加していますね。
そして、そのリスト(Vectorオブジェクト)を戻り値として返しています。

ただし、引数のstayDateはGregorianCalendar型であり、そのままではデータベースの
検索には使用できないので、

         selectPs.setDate(2, new Date(stayDate.getTimeInMillis()));

というコードでGregorianCalendar型からjava.sql.Date型に変換してからsetDate()
を実行しています。
このやり方は、vol.044に出てきましたね。忘れた人は復習して下さい。

残りのソース・コードは解説しなくても理解できることと思います。

なお、このgetBookedRoomNum()メソッドでは、宿泊予定日を1日分しか指定できない
ため、宿泊日数が複数ある場合はその日数分だけ複数回メソッドを呼び出して検索
を行う必要があります。



では続いて、部屋の予約をするためにデータベースにアクセスするクラスを
作成しましょう。
部屋の予約はBOOKINGテーブルとROOMBOOKテーブルにレコードを追加することによって
行われます。

では、同じパッケージの中にBookingDbManagerというクラス名で下記のような
内容のクラスを作成してください。

--------------------------------------------------------
package jp.co.flsi.lecture.webservice.hotel.db;

import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Calendar;
import java.util.GregorianCalendar;

import org.apache.log4j.Logger;

public class BookingDbManager extends DbManager {
   private static final String selectMaxBooknumSql = "SELECT MAX(BOOKNUM) FROM BOOKING";
   private static final String insertBookingSql = "INSERT INTO BOOKING  VALUES (?, ?, ?, ?)";
   private static final String insertRoombookSql = "INSERT INTO ROOMBOOK  VALUES (?, ?, ?, ?)";
   private static Logger logger = Logger.getLogger(BookingDbManager.class);

   public static void insertData(int roomNum, String customerName, String address, String telNum,
         GregorianCalendar startStayDate, int stayNights, int lodgers) throws HotelDbException {
      logger.info("Start ...............");
      try {
         Statement selectSt = conn.createStatement();
         PreparedStatement insertBookingPs = conn.prepareStatement(insertBookingSql);
         PreparedStatement insertRoombookPs = conn.prepareStatement(insertRoombookSql);
         ResultSet rs = selectSt.executeQuery(selectMaxBooknumSql);
         int newBookingNumber = 1;
         if (rs.next()) newBookingNumber = rs.getInt(1) + 1;
         insertBookingPs.setInt(1, newBookingNumber);
         insertBookingPs.setString(2, customerName);
         insertBookingPs.setString(3, address);
         insertBookingPs.setString(4, telNum);
         insertBookingPs.executeUpdate();
         GregorianCalendar stayDate = (GregorianCalendar) startStayDate.clone();
         for (int i = 0; i < stayNights; i++) {
            insertRoombookPs.setInt(1, roomNum);
            insertRoombookPs.setDate(2, new Date(stayDate.getTimeInMillis()));
            insertRoombookPs.setInt(3, newBookingNumber);
            insertRoombookPs.setInt(4, lodgers);
            insertRoombookPs.executeUpdate();
            stayDate.add(Calendar.DAY_OF_MONTH, 1);
         }
         selectSt.close();
         insertBookingPs.close();
         insertRoombookPs.close();
         conn.commit();
      }
      catch (SQLException e) {
         logger.error(e);
         throw new HotelDbException("Error: insertData() failed!", e);
      }
      finally {
         logger.info("End ...............");
      }
   }
  
}
--------------------------------------------------------

ここで、clone()というメソッドは、そのオブジェクトのコピーを作るメソッドです。
引数のstartStayDate自体を変更してしまっては呼び出し元に影響を与えてしまうため
このようにいったんコピーを作ってから、そのコピーに対して変更(ここでは
            stayDate.add(Calendar.DAY_OF_MONTH, 1);
というコードによって、日を1日増やしている)を行っています。



(次回に続く)


では、今日はここまでにします。



┏━━━━━━━━━━━━━━━━━━━━━━━━━━━┓
★ホームページ:
      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) 2009 Future Lifestyle Inc. 不許無断複製