앞서 모든 지점 조회 기능을 구현해 보았습니다.
기능이 너무 단순했기 때문에
은행 지점에 관해서 추가할 새로운 기능에 대해서 생각해보았습니다.
그러던 와중 "은행 방문 예약 기능"을 구현 해 보고 싶었습니다.
은행 방문 예약 기능을 구현하려면 먼저 테이블을 추가해야 했기 때문에
Reservation 테이블을 추가했습니다.

Reservation 테이블은 User 테이블과 Bank 테이블의 중간 테이블로 구현하였습니다.
| Application |
public static void makeReservation() throws Exception {
List<Bank> banks = bankController.findAllBanks();
int showBankChoice = ConsoleUtility.promptForChoice("위의 지점중 예약할 지점을 선택해주세요", 1, banks.size());
int choseBankId = banks.get(showBankChoice - 1).getId();
List<Reservation> reservations = reservationController.findAllReservationsById(choseBankId);
// 예약이 가능한 시간 출력
reservationController.printAvailableTime(reservations, choseBankId, banks);
int choseReservationTime = ConsoleUtility.promptForChoice("위의 시간중 예약할 시간을 입력해주세요", 8, 15);
// 유저가 선택한 시간이 예약 가능한 시간인지 판별
boolean availableTime = reservationController.isAvailableTime(choseBankId, choseReservationTime);
if (availableTime) {
System.out.println("예약 가능한 시간입니다.");
reservationController.createReservation(userState.getUid(), choseReservationTime, choseBankId);
System.out.println("예약이 완료되었습니다.");
} else {
System.out.println("예약 불가능한 시간입니다.");
}
}
위의 코드는 Application(실행) 클래스입니다.
콘솔로 출력하고 입력을 받기 때문에 Application에서 간단한 입출력을 담당하도록 만들었습니다.
다 만들고 나니 Main 클래스가 너무 지저분해보여 Controller나 Service단에서 입출력을 담당하도록 하는게 더 나을거 같다는 생각이 들었습니다.
예약기능의 간단한 Flow는 이렇습니다.
-> 아까 만들었던 findAllBank()로 모든 은행 지점을 불러와줍니다.
-> 유저가 은행 지점을 선택하면, 해당 지점에서 예약이 가능한 시간만 유저에게 보여주도록 합니다.
-> 유저가 예약할 시간을 입력하면 해당 시간이 예약 가능한 시간인지 다시 한번 검증한 후 가능하면 예약완료시킵니다.
먼저, 지점 선택 후 예약 가능한 시간만 유저에게 보여주는 기능에 대해서 알아보도록 하겠습니다.
| ReservationRepository |
@Override
public List<Reservation> findAllReservationsById(int bankId) throws Exception {
List<Reservation> banks = new ArrayList<>();
String sql = "SELECT * FROM Reservation WHERE bankId ="+bankId;
try (Connection conn = DB.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
banks.add(extractReservation(rs));
}
}
return banks;
}
먼저 해당 지점에 예약된 모든 예약들을 반환합니다.
| ReservationController |
@Override
public void printAvailableTime(List<Reservation> reservations,int choseBankId,List<Bank> banks) throws Exception {
boolean isReservated = false;
System.out.println("* "+banks.get(choseBankId-1).getName()+"의 예약 가능한 시간");
System.out.print("< ");
for (int i = 0; i<=7;i++){
isReservated = false;
for (int j = 0; j < reservations.size(); j++) {
if((i+8) == reservations.get(j).getReservationTime()){
isReservated = true;
}
}
if(isReservated == false){
System.out.print((i+8)+"시 ");
}
} // 해당 지점에 예약이 되어있는 시간을 제외하고 모두 출력해줌
System.out.println(">");
System.out.println();
}
앞에서 모든 예약 시간을 받아온 후,
다시 Service단에서 영업시간 내에 예약이 되어있는 시간을 제외하고 모두 반환해줍니다.

| ReservationRepository |
@Override
public boolean isAvailableTime(int choseBankId,int choseReservationTime) throws Exception {
List<Reservation> reserved = new ArrayList<>();
String sql = "SELECT * FROM Reservation WHERE bankId ="+choseBankId+" and reservationTime = "+choseReservationTime;
try (Connection conn = DB.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql);
ResultSet rs = stmt.executeQuery()) {
while (rs.next()) {
reserved.add(extractReservation(rs));
}
}
if(reserved.size()==0){
return true;
}
return false;
}
다음으론 유저가 중복된 예약시간을 입력 했을 수도 있기 때문에 한번 더 검증하는 과정이 필요하다고 생각했습니다.
그래서 선택된 지점id와 시간이 일치하는 튜플이 있는지 살펴보고 가져온 후,
가져온 값이 없으면 true를 반환, 가져온 값이 있으면 중복이 있는것을 뜻하기 때문에 false를 반환하도록 구현하였습니다.
| Application |
if (availableTime) {
System.out.println("예약 가능한 시간입니다.");
reservationController.createReservation(userState.getUid(), choseReservationTime, choseBankId);
System.out.println("예약이 완료되었습니다.");
} else {
System.out.println("예약 불가능한 시간입니다.");
}
| ReservationRepository |
@Override
public void createReservation(int UserId, int choseReservationTime, int choseBankId) throws Exception {
String sql = "INSERT INTO Reservation (reservationTime, bankId, userId) VALUES (?, ?, ?)";
try (Connection conn = DB.getConnection();
PreparedStatement stmt = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS)) {
stmt.setInt(1, choseReservationTime);
stmt.setInt(2, choseBankId);
stmt.setInt(3, UserId);
int affectedRows = stmt.executeUpdate();
}
}
마지막으로 검증이 끝난 후, 해당 예약을 DB에 추가해줍니다.

이후 다시 들어가보면

이렇게 방금 예약했던 8시가 빠져있는것을 확인할 수 있습니다.
'🚀Project' 카테고리의 다른 글
| Trouble Shooting (0) | 2024.04.22 |
|---|---|
| [은행시스템] 코드 리팩토링 #5 (0) | 2024.04.01 |
| [은행시스템] 최종 #4 (0) | 2024.03.31 |
| [은행시스템] 모든 지점 조회 기능 #2 (0) | 2024.03.31 |
| [은행시스템] 주제선정 및 ERD설계 #1 (0) | 2024.03.31 |