diff --git a/src/database/CakeOrderSystem.java b/src/database/CakeOrderSystem.java index 198d29c..e489a61 100644 --- a/src/database/CakeOrderSystem.java +++ b/src/database/CakeOrderSystem.java @@ -19,8 +19,8 @@ public class CakeOrderSystem { public static void 메뉴(Connection conn) { Scanner scanner = new Scanner(System.in); - - //addOrder에서 주문을 계속하지 않음을 선택했을 때 다시 메뉴 선택창으로 돌아오도록 while문으로 감쌌습니다. + + // addOrder에서 주문을 계속하지 않음을 선택했을 때 다시 메뉴 선택창으로 돌아오도록 while문으로 감쌌습니다. while (true) { System.out.println(); System.out.println("1. 케이크 주문하기"); @@ -83,12 +83,12 @@ private static void addOrder(Connection conn) { LocalDate date = LocalDate.now(); // 현재 날짜 불러오기 addOrdersTable(conn, ordersID, customerID, date); boolean more = true; // 주문을 계속할 건지 확인하는 변수 - + // 케이크 메뉴 및 재고 현황 출력 showCakeMenu(conn); // 케이크 판매 순위 출력 showBestCake(conn); - + while (more) { System.out.print("주문할 케이크 ID를 입력하세요(ex):C001):"); String cakeID = sc.nextLine(); @@ -96,27 +96,26 @@ private static void addOrder(Connection conn) { // 주문 계속 진행 System.out.print("수량을 입력하세요: "); int quantity = Integer.parseInt(sc.nextLine()); - + // 재고가 존재하는지 확인 int stock = getAvailableStock(conn, cakeID); - if(stock>=quantity) { + if (stock >= quantity) { // orderitem 테이블에 data 추가 String orderItemID = "I0" + Integer.toString(orderitem_index); addOrderitemTable(conn, orderItemID, ordersID, cakeID, quantity); orderitem_index++; - + // 재고 감소 updateInventoryTable(conn, quantity, cakeID); - + System.out.print("더 주문하시겠습니까? (Y/N): "); String answer = sc.nextLine().toUpperCase(); if (!answer.equals("Y")) { more = false; } - } - else { + } else { System.out.println("재고가 부족합니다. 현재 재고: " + stock + "개"); - System.out.println("다시 케이크를 선택해주세요."); + System.out.println("다시 케이크를 선택해주세요."); } } else { // 케이크 ID가 DB에 존재하지 않으면 System.out.println("존재하지 않는 케이크 ID입니다. 다시 입력해주세요."); @@ -127,27 +126,45 @@ private static void addOrder(Connection conn) { private static void updateInventoryTable(Connection conn, int quantity, String cakeID) { // 재고 업데이트 query문 String sql = "UPDATE inventory SET quantity_available = quantity_available - ? WHERE cake_id = ?"; - try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setInt(1, quantity); - ps.setString(2, cakeID); - ps.executeUpdate(); - } catch (SQLException e) { - e.printStackTrace(); - } + try { + conn.setAutoCommit(false); // 트랜잭션 시작 + + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setInt(1, quantity); + ps.setString(2, cakeID); + ps.executeUpdate(); + } + conn.commit(); // 성공 시 커밋 + + } catch (SQLException e) { + try { + conn.rollback();// 실패시 롤백 + System.out.println("재고 감소에 실패하여 롤백합니다."); + } catch (SQLException rollbackEx) { + rollbackEx.printStackTrace(); + } + e.printStackTrace(); + } finally { + try { + conn.setAutoCommit(true); // 자동 커밋 복구 + } catch (SQLException e) { + e.printStackTrace(); + } + } } private static int getAvailableStock(Connection conn, String cakeID) { // inventory 테이블에서 재고 불러오는 query문 String sql = "SELECT quantity_available FROM inventory WHERE cake_id = ?"; - try (PreparedStatement ps = conn.prepareStatement(sql)) { - ps.setString(1, cakeID); - ResultSet rs = ps.executeQuery(); - if (rs.next()) { - return rs.getInt("quantity_available"); - } - } catch (SQLException e) { - e.printStackTrace(); - } + try (PreparedStatement ps = conn.prepareStatement(sql)) { + ps.setString(1, cakeID); + ResultSet rs = ps.executeQuery(); + if (rs.next()) { + return rs.getInt("quantity_available"); + } + } catch (SQLException e) { + e.printStackTrace(); + } return 0; // 존재하지 않는 경우, 에러가 생긴 경우 } @@ -155,99 +172,90 @@ private static void showCakeMenu(Connection conn) { // cake_view라는 view에서 정보 가져오는 query문 String query = "SELECT cake_id, cake_name, price, quantity FROM cake_view"; - try (Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query)) { - - // 케이크 메뉴표 출력 - System.out.println("[케이크 메뉴표]"); - System.out.println("-------------------------------------------------"); - System.out.printf("%-10s %-20s %-8s %-5s%n", "케이크ID", "케이크 이름", "가격", "재고"); - System.out.println("-------------------------------------------------"); - - while (rs.next()) { - String id = rs.getString("cake_id"); - String name = rs.getString("cake_name"); - int price = rs.getInt("price"); - int quantity = rs.getInt("quantity"); - - System.out.printf("%-10s %-20s %-8d %-5d%n", id, name, price, quantity); - } - System.out.println("-------------------------------------------------"); - - } catch (SQLException e) { - System.out.println("케이크 메뉴 조회 실패"); - e.printStackTrace(); - } - + try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(query)) { + + // 케이크 메뉴표 출력 + System.out.println("[케이크 메뉴표]"); + System.out.println("-------------------------------------------------"); + System.out.printf("%-10s %-20s %-8s %-5s%n", "케이크ID", "케이크 이름", "가격", "재고"); + System.out.println("-------------------------------------------------"); + + while (rs.next()) { + String id = rs.getString("cake_id"); + String name = rs.getString("cake_name"); + int price = rs.getInt("price"); + int quantity = rs.getInt("quantity"); + + System.out.printf("%-10s %-20s %-8d %-5d%n", id, name, price, quantity); + } + System.out.println("-------------------------------------------------"); + + } catch (SQLException e) { + System.out.println("케이크 메뉴 조회 실패"); + e.printStackTrace(); + } + } public static void showBestCake(Connection conn) { // 가장 많이 팔린 케이크 순위 query 문 - String query = "SELECT c.cake_id, c.cake_name, SUM(oi.quantity) AS total_sold " - + "FROM orderitem oi " - + "JOIN cake c ON oi.cake_id = c.cake_id " - + "GROUP BY c.cake_id, c.cake_name " - + "ORDER BY total_sold DESC " - + "LIMIT 5"; - - try (Statement stmt = conn.createStatement(); - ResultSet rs = stmt.executeQuery(query)) { - - System.out.println("\n[가장 많이 팔린 케이크 목록]"); - System.out.println("------------------------------------"); - System.out.printf("%-10s %-20s | %s\n", "케이크ID", "케이크 이름", "판매수량"); - System.out.println("------------------------------------"); - - while (rs.next()) { - String cakeID = rs.getString("cake_id"); - String cakeName = rs.getString("cake_name"); - int totalSold = rs.getInt("total_sold"); - System.out.printf("%-10s %-20s | %d\n", cakeID, cakeName, totalSold); - } - System.out.println("------------------------------------"); - } catch (SQLException e) { - e.printStackTrace(); - } + String query = "SELECT c.cake_id, c.cake_name, SUM(oi.quantity) AS total_sold " + "FROM orderitem oi " + + "JOIN cake c ON oi.cake_id = c.cake_id " + "GROUP BY c.cake_id, c.cake_name " + + "ORDER BY total_sold DESC " + "LIMIT 5"; + + try (Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(query)) { + + System.out.println("\n[가장 많이 팔린 케이크 목록]"); + System.out.println("------------------------------------"); + System.out.printf("%-10s %-20s | %s\n", "케이크ID", "케이크 이름", "판매수량"); + System.out.println("------------------------------------"); + + while (rs.next()) { + String cakeID = rs.getString("cake_id"); + String cakeName = rs.getString("cake_name"); + int totalSold = rs.getInt("total_sold"); + System.out.printf("%-10s %-20s | %d\n", cakeID, cakeName, totalSold); + } + System.out.println("------------------------------------"); + } catch (SQLException e) { + e.printStackTrace(); + } } // case 2 : 전체 주문 목록 조회 - - orders_ID와 orders_date 확인가능 private static void showCustomerOrder(Connection conn, String customerName) { String query = "SELECT orders_id, orders_date FROM customer_order_view WHERE customer_name = ?"; - - try (PreparedStatement ps = conn.prepareStatement(query)) { - ps.setString(1, customerName); - try (ResultSet rs = ps.executeQuery()) { - boolean hasResults = false; - System.out.println(customerName + " 님의 주문 내역:"); - while (rs.next()) { - String orderId = rs.getString("orders_id"); - Date orderDate = rs.getDate("orders_date"); - System.out.println(" - 주문ID: " + orderId + ", 주문일: " + orderDate); - hasResults = true; - } - - if (!hasResults) { - System.out.println("해당 고객의 주문 내역이 없습니다."); - } - - } - } catch (SQLException e) { - e.printStackTrace(); - System.out.println("주문 내역 조회 중 오류가 발생했습니다."); - } + + try (PreparedStatement ps = conn.prepareStatement(query)) { + ps.setString(1, customerName); + try (ResultSet rs = ps.executeQuery()) { + boolean hasResults = false; + System.out.println(customerName + " 님의 주문 내역:"); + while (rs.next()) { + String orderId = rs.getString("orders_id"); + Date orderDate = rs.getDate("orders_date"); + System.out.println(" - 주문ID: " + orderId + ", 주문일: " + orderDate); + hasResults = true; + } + + if (!hasResults) { + System.out.println("해당 고객의 주문 내역이 없습니다."); + } + + } + } catch (SQLException e) { + e.printStackTrace(); + System.out.println("주문 내역 조회 중 오류가 발생했습니다."); + } } // case 3 : 현재 주문 내역 상세 - orders_id, 전체 수량, 총 가격 private static void showOrderDetail(Connection conn, String orderId) { - String orderInfoSQL = "SELECT o.orders_date, c.customer_name AS customer_name " + - "FROM orders o " + - "JOIN customer c ON o.customer_id = c.customer_id " + - "WHERE o.orders_id = ?"; - String orderItemsSQL = "SELECT ca.cake_name AS cake_name, ca.cake_id AS cake_id, ca.price, oi.quantity " + - "FROM orderitem oi " + - "JOIN cake ca ON oi.cake_id = ca.cake_id " + - "WHERE oi.orders_id = ?"; - + String orderInfoSQL = "SELECT o.orders_date, c.customer_name AS customer_name " + "FROM orders o " + + "JOIN customer c ON o.customer_id = c.customer_id " + "WHERE o.orders_id = ?"; + String orderItemsSQL = "SELECT ca.cake_id, ca.cake_name AS cake_name, ca.price AS price, SUM(oi.quantity) AS total_quantity, SUM(oi.quantity*ca.price) AS total_price " + + "FROM orderitem oi " + "JOIN cake ca on oi.cake_id = ca.cake_id " + "WHERE oi.orders_id = ? " + + "GROUP BY ca.cake_name, ca.price, ca.cake_id "; try (PreparedStatement orderInfoStmt = conn.prepareStatement(orderInfoSQL); PreparedStatement orderItemsStmt = conn.prepareStatement(orderItemsSQL)) { // 1. 주문 기본 정보 조회 @@ -268,10 +276,11 @@ private static void showOrderDetail(Connection conn, String orderId) { String cakeName = itemRs.getString("cake_name"); String CakeID = itemRs.getString("cake_id"); int price = itemRs.getInt("price"); - int quantity = itemRs.getInt("quantity"); - int subtotal = price * quantity; + int quantity = itemRs.getInt("total_quantity"); + int subtotal = itemRs.getInt("total_price"); total += subtotal; - System.out.printf("케이크: %s(%s) | 가격: %d | 수량: %d | 소계: %d\n", cakeName, CakeID, price, quantity, subtotal); + System.out.printf("케이크: %s(%s) | 가격: %d | 수량: %d | 소계: %d\n", cakeName, CakeID, price, + quantity, subtotal); } System.out.println("---------------------------------"); System.out.println("[총 주문 금액]: " + total + "원"); @@ -293,7 +302,7 @@ private static void updateOrder(Connection conn) { System.out.print("수정 또는 삭제할 주문 ID를 입력하세요 (ex: O001): "); String orderId = sc.nextLine(); System.out.println("1.주문 삭제 "); - System.out.println("2.주문 정보 수정 (주문한 케이크 수량 변경)"); + System.out.println("2.주문 정보 수정 (케이크 및 수량 변경)"); System.out.print("메뉴 선택: "); int choice = Integer.parseInt(sc.nextLine()); @@ -333,22 +342,46 @@ else if (choice == 2) { System.out.print("새로운 수량을 입력하세요: "); int newQty = Integer.parseInt(sc.nextLine()); + String updateSQL = "UPDATE orderitem SET cake_id = ?, quantity = ? WHERE orders_id = ? AND cake_id = ?"; - try (PreparedStatement stmt = conn.prepareStatement(updateSQL)) { - stmt.setString(1, newCakeId); - stmt.setInt(2, newQty); - stmt.setString(3, orderId); - stmt.setString(4, oldCakeId); - - int rows = stmt.executeUpdate(); - if (rows > 0) { - System.out.println("주문이 수정되었습니다."); - } else { - System.out.println("해당 주문 또는 케이크 ID를 찾을 수 없습니다."); + + try { + conn.setAutoCommit(false); // 트랜잭션 시작 + + try (PreparedStatement stmt = conn.prepareStatement(updateSQL)) { + stmt.setString(1, newCakeId); + stmt.setInt(2, newQty); + stmt.setString(3, orderId); + stmt.setString(4, oldCakeId); + + int rows = stmt.executeUpdate(); + if (rows > 0) { + conn.commit(); // 성공 시 커밋 + System.out.println("주문이 수정되었습니다."); + } else { + System.out.println("해당 주문 또는 케이크 ID를 찾을 수 없습니다."); + conn.rollback(); // 실패 시 롤백 + } } + } catch (SQLException e) { + try { + conn.rollback(); // 예외 발생 시 롤백 + System.out.println("오류 발생으로 주문 수정 작업을 취소했습니다."); + } catch (SQLException rollbackEx) { + rollbackEx.printStackTrace(); + } e.printStackTrace(); + } finally { + try { + conn.setAutoCommit(true); // 트랜잭션 원복 + } catch (SQLException e) { + e.printStackTrace(); + } } + + } else { + System.out.println("잘못된 선택입니다."); } } @@ -455,19 +488,42 @@ else if (choice == 2) { System.out.print("새 전화번호를 입력하세요(변경하지 않는다면 동일한 번호 입력): "); // 전화번호 수정 String newPhone = sc.nextLine(); - String updateSQL = "UPDATE customer SET customer_name = ?, phone_number = ? WHERE customer_id = ?"; // 테이블에 수정사항 업데이트 - try (PreparedStatement stmt = conn.prepareStatement(updateSQL)) { - stmt.setString(1, newName); - stmt.setString(2, newPhone); - stmt.setString(3, customerId); - stmt.executeUpdate(); + String updateSQL = "UPDATE customer SET customer_name = ?, phone_number = ? WHERE customer_id = ?"; // 테이블에 + // 수정사항 + // 업데이트 + try { + conn.setAutoCommit(false); // 트랜잭션 시작 + + try (PreparedStatement stmt = conn.prepareStatement(updateSQL)) { + stmt.setString(1, newName); + stmt.setString(2, newPhone); + stmt.setString(3, customerId); + int rows = stmt.executeUpdate(); + + if (rows > 0) { + conn.commit(); // 성공 시 커밋 + System.out.println("고객 정보가 수정되었습니다."); + } else { + System.out.println("고객 정보를 찾을 수 없습니다."); + conn.rollback(); // 실패 시 롤백 + } + } - System.out.println("고객 정보가 수정되었습니다."); } catch (SQLException e) { + try { + conn.rollback(); + System.out.println("오류 발생으로 고객 정보 수정 작업을 취소했습니다."); + } catch (SQLException rollbackEx) { + rollbackEx.printStackTrace(); + } e.printStackTrace(); + } finally { + try { + conn.setAutoCommit(true); // 자동 커밋 복원 + } catch (SQLException e) { + e.printStackTrace(); + } } - } else { - System.out.println("잘못된 선택입니다."); } } @@ -488,7 +544,8 @@ public static boolean isValidCakeId(Connection conn, String cakeId) { // 이름 입력을 통해 customerID를 찾고, 없을 경우 고객 정보 추가하는 함수 public static String findCustomerID(Connection conn, String name) { Scanner sc = new Scanner(System.in); - String query = "SELECT customer_id FROM customer WHERE customer_name = ?"; // 고객 테이블에 name이 아니라 customer_name으로 되어있어서 수정했습니다. + String query = "SELECT customer_id FROM customer WHERE customer_name = ?"; // 고객 테이블에 name이 아니라 customer_name으로 + // 되어있어서 수정했습니다. try (PreparedStatement stmt = conn.prepareStatement(query)) { stmt.setString(1, name); try (ResultSet rs = stmt.executeQuery()) { @@ -496,7 +553,7 @@ public static String findCustomerID(Connection conn, String name) { return rs.getString("customer_id"); } else { // 고객 정보가 존재하지 않을 경우 System.out.println("고객 정보가 존재하지 않아 새로 추가합니다."); - System.out.println("전화번호를 입력하세요(ex)010-1111-2222): "); + System.out.print("전화번호를 입력하세요(ex)010-1111-2222): "); String phone_num = sc.nextLine(); String customerID = "U0" + Integer.toString(customer_index); customer_index++; // 변수 값 증가 -> 이후에 적용 @@ -515,7 +572,7 @@ public static String findCustomerID(Connection conn, String name) { private static void addCustomerTable(Connection conn, String customerID, String name, String phone_num) { // customer 테이블 insert query문 String sql = "INSERT INTO customer (customer_id, customer_name, phone_number) VALUES (?, ?, ?)"; - + try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, customerID); stmt.setString(2, name); @@ -530,7 +587,8 @@ private static void addCustomerTable(Connection conn, String customerID, String // orders 테이블에 데이터 추가 함수 private static void addOrdersTable(Connection conn, String ordersID, String customerID, LocalDate date) { // orders 테이블에 데이터 insert query문 - String sql = "INSERT INTO orders (orders_id, customer_id, orders_date) VALUES (?, ?, ?)"; // OrderItem에 추가하는 쿼리로 돼있어서 수정했습니다. + String sql = "INSERT INTO orders (orders_id, customer_id, orders_date) VALUES (?, ?, ?)"; // OrderItem에 추가하는 쿼리로 + // 돼있어서 수정했습니다. try (PreparedStatement stmt = conn.prepareStatement(sql)) { stmt.setString(1, ordersID); stmt.setString(2, customerID); @@ -544,7 +602,8 @@ private static void addOrdersTable(Connection conn, String ordersID, String cust } // orderitem 테이블에 데이터 추가 함수 - private static void addOrderitemTable(Connection conn, String orderItemID, String ordersID, String cakeID, int quantity) { + private static void addOrderitemTable(Connection conn, String orderItemID, String ordersID, String cakeID, + int quantity) { // orderitem 테이블에 데이터 insert 함수 String sql = "INSERT INTO orderitem (order_item_id, orders_id, cake_id, quantity) VALUES (?, ?, ?, ?)"; try (PreparedStatement stmt = conn.prepareStatement(sql)) { @@ -563,11 +622,12 @@ private static void addOrderitemTable(Connection conn, String orderItemID, Strin public static void main(String[] args) { Connection conn = sql_connection.getConnection(); // DB 연결 - SQLExecutor.executeSQLFile(conn, "src/sql/create_table.sql"); // 테이블 만들기 - SQLExecutor.executeSQLFile(conn, "src/sql/insert_data.sql"); // 데이터 넣기 + SQLExecutor.executeSQLFile(conn, "src/sql/dropschema.sql"); // drop 테이블 + SQLExecutor.executeSQLFile(conn, "src/sql/createschema.sql"); // 테이블 만들기 + SQLExecutor.executeSQLFile(conn, "src/sql/initdata.sql"); // 데이터 넣기 초기화면(); 메뉴(conn); // DB 연결 이어서 가져감 sql_connection.close(); } -} \ No newline at end of file +}