목차
- VIEW
1-1. View 클래스 작성
1. VIEW
MVC 패턴은 Model, View, Controller를 일컫는다.
View ↔ Controller ↔ Service ↔ DAO ↔ DB로 흐름이 이어진다.
A. 모든 카테고리 조회
-- order-query.xml
<entry key="selectAllCategory">
SELECT
A.CATEGORY_CODE
, A.CATEGODY_NAME
FROM TBL_CATEGORY A
</entry>
- XML 파일에 쿼리문을 작성한다.
-- OrderDAO.class
private Properties prop = new Properties();
public OrderDAO() {
try {
prop.loadFromXML(new FileInputStream("mapper/order-query.xml"));
} catch (IOException e) {
e.printStackTrace();
}
}
public List<CategoryDTO> selectAllCategory(Connection con) {
PreparedStatement pstmt = null;
ResultSet rset = null;
List<CategoryDTO> categoryList = null;
String query = prop.getProperty("selectAllCategory");
try {
pstmt = con.prepareStatement(query);
rset = pstmt.executeQuery();
categoryList = new ArrayList<>(); //Exception에 걸리지 않도록 pstmt, rset 모두 수행한 다음에 생성
while(rset.next()) {
CategoryDTO category = new CategoryDTO();
category.setCode(rset.getInt("CATEGORY_CODE"));
category.setName(rset.getString("CATEGORY_NAME"));
categoryList.add(category);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return categoryList;
}
- DAO 클래스에서는 프로퍼티(Properties)를 다룰 것이므로 private 필드로 선언한 뒤 기본 생성자 통해 읽어온다.
-- OrderService.class
private OrderDAO orderDAO = new OrderDAO();
public List<CategoryDTO> selectAllCategory() {
Connection con = getConnection(); //① Connection 생성
List<CategoryDTO> categoryList = orderDAO.selectAllCategory(con); //② DAO 클래스에서 관련 메소드 호출
close(con); //③ Connection 반환
return categoryList; //④ 반환 받은 값 리턴
- Service 클래스에서 전반적으로 쓰일 OrderDAO 객체는 private 필드로 선언한다.
- 순서대로 작성한다. 쿼리문이 SELECT이므로 트랜잭션 제어는 필요치 않다: ① Connection 생성, ② DAO 클래스에서 관련 메소드 호출하여 결과 리턴 받기, ③ Connection 반환, ④ 반환 받은 값 리턴
B. 카테고리별 메뉴 조회
-- order-query.xml
<entry key="selectMenuByCategory>
SELECT
A.MENU_CODE
, A.MENU_NAME
, A.MENU_PRICE
, A.CATEGORY_CODE
, A.ORDERABLE_STATUS
FROM TBL_MENU A
WHERE A.ORDERABLE_STATUS = 'Y'
AND A.CATEGORY_CODE = ?
</entry>
- 사용자가 고른 카테고리별 주문 가능 메뉴 리스트를 출력하고자 한다. 때문에 쿼리문의 WHERE절에서 판매 여부(ORDERABLE_STATUS)를 확인하고, 입력된 카테고리 코드를 반영할 수 있도록 작성한다.
-- OrderDAO.class
public List<MenuDTO> selectMenuByCategory(Connection con, int categoryCode) {
PreparedStatement pstmt = null;
ResultSet rset = null;
List<MenuDTO> menuList = null;
String query = prop.getProperty("selectMenuByCategory");
try {
pstmt = con.prepareStatement(query);
pstmt.setInt(1, categoryCode); //인자로 넘겨받은 categoryCode를 적용
rset = pstmt.executeQuery();
menuList = new ArrayList<>();
while(rset.next()) {
MenuDTO menu = new MenuDTO();
menu.setCode(rset.getInt("MENU_CODE");
menu.setName(rset.getString("MENU_NAME");
menu.setPrice(rset.getInt("MENU_PRICE");
menu.setCategoryCode(rset.getInt("CATEGORY_CODE");
menu.setOrderableStatus(rset.getString("ORDERABLE_STATUS");
menuList.add(menu);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(rset);
close(pstmt);
}
return menuList;
}
- 위치홀더로 남겨둔 카테고리 코드를 인자로 넘겨받은 categoryCode 값으로 적용한다.
-- OrderService.class
public List<MenuDTO> selectByCategory(int categoryCode) {
Connection con = getConnection();
List<MenuDTO> menuList = orderDAO.selectMenuByCategory(con, categoryCode);
close(con);
return menuList;
- Service 클래스 작성 순서에 따라 기입한다: ① Connection 생성, ② DAO 클래스와 메소드 호출해 리턴 받을 변수에 적용, ③ (SELECT 구문이므로 트랜잭션 제어 대상 아님) Connection 반납, ④ 결과 반환
C. 주문 메뉴 추가
D. 주문 메뉴 목록 추가
-- order-query.xml
<entry key="insertMenu"> //주문 메뉴 추가
INSERT
INTO TBL_ORDER A
(
A.ORDER_CODE
, A.ORDER_DATE
, A.ORDER_TIME
, A.TOTAL_ORDER_PRICE
)
VALUES
(
SEQ_ORDER_CODE.NEXTVAL
, ?
, ?
, ?
)
</entry>
<entry key="insertOrderMenu"> //주문 메뉴 목록 추가
INSERT
INTO TBL_ORDER_MENU A
(
A.ORDER_CODE
, A.MENU_CODE
, A.ORDER_AMOUNT
)
VALUES
(
SEQ_ORDER_CODE.CURRVAL
, ?
, ?
)
</entry>
-- OrderDAO.class
public int insertOrder(Connection con, OrderDTO order) { //주문 정보 입력용 메소드
PreparedStatement pstmt = null;
int result = 0;
String query = prop.getQuery("insertMenu");
try {
pstmt = con.prepareStatement(query);
pstmt.setString(1, order.getDate());
pstmt.setString(2, order.getTime());
pstmt.setInt(3, order.getTotalOrderPrice());
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
}
return result;
}
public int insertOrderMenu(Connection con, OrderMenuDTO orderMenu) { //주문 메뉴별 입력용 메소드
PreparedStatement pstmt = null;
int result = 0;
String query = prop.getProperty("insertOrderMenu");
try {
pstmt = con.prepareStatement(query);
pstmt.setInt(1, orderMenu.getMenuCode());
pstmt.setInt(2, orderMenu.getOrderAmount());
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(pstmt);
}
return result;
}
- 주문 메뉴를 추가하고, 주문 메뉴 목록 또한 별도 테이블에 추가할 것이다.
- 주문 메뉴 목록 추가 시 코드는 주문 코드의 CURRVAL로 설정한다: 1번 - 음식A, 음식B, 음료A, 음료B...
-- OrderService.class
public int registOrder(OrderDTO order) {
Connection con = getConnection();
int result = 0; //최종 결과 판단할 변수
int orderResult = orderDAO.insertOrder(con, order); //주문 정보 INSERT
List<OrderMenuDTO> orderMenuList = order.getOrderMenuList(); //주문 메뉴 목록 INSERT
int orderMenuResult = 0;
for(OrderMenuDTO orderMenu : orderMenuList) {
orderMenuResult += orderDAO.insertOrderMenu(con, orderMenu);
}
- result 변수에는 전체적으로 주문 정보 및 주문 메뉴 목록에 대한 등록이 모두 잘 되었는지 결과를 저장해 확인한다.
- 주문 메뉴 목록은 1개 이상일 수 있으므로 orderMenuList의 개수만큼 담을 수 있도록 List로 선언한다.
- orderMenuResult += 는 List 사이즈만큼 INSERT 작업 수행하며 결과를 계속 누적한다.
if(orderResult > 0 && orderMenuList == orderMenuList.size()) {
commit(con);
result = 1;
} else {
rollback(con);
}
- Servicer 클래스에서 트랜잭션 처리가 필요하다.
- 주문 정보 INSERT 결과가 0보다 크고, orderMenuList가 주문 목록 개수와 같으면 커밋(commit)한다. 반대의 경우는 롤백(rollback)임을 기재한다.
close(con);
return result;
}
- 사용한 Connection 객체에 대해 자원 반납 처리하고, 결과값을 반환한다.
1-1. View 클래스 작성
- 사용자에게 메뉴판을 보여주듯 콘솔창에 반복 출력될 구문을 작성한다.
-- OrderMenu.class
private OrderService orderService = new OrderService();
public void displayMenu() {
Scanner sc = new Scanner(System.in);
do {
System.out.prinln("======= 음식 주문 프로그램 =======");
List<CategoryDTO> categoryList = orderService.selectAllCategory();
for(Category category : categoryList) {
System.out.println(category.getName());
}
System.out.println("===========================");
System.out.println("주문할 카테고리를 선택해 주세요 : ");
String inputCategory = sc.nextLine();
int categoryCode = 0;
for(CategoryDTO category : categoryList) {
if(category.getName().equals(inputCategory)) {
categoryCode = category.getCode();
}
}
System.out.println("======= 주문 가능 메뉴 =======");
List<MenuDTO> menuList = orderService.selectByCategory(categoryCode);
for(MenuDTO menu : menuList) {
System.out.println(menu);
}
System.out.println("주문하실 메뉴를 선택해 주세요 : ");
String inputMenu = sc.nextLine();
int menuCode = 0;
int menuPrice = 0;
for(int i=0; i < menuList.size(); i++) {
MenuDTO menu = menuList.get(i);
if(menu.getName().equals(inputMenu)) {
menuCode = menu.getCode();
menuPrice = menu.getPrice();
}
}
System.out.println("주문하실 수량을 입력하세요 : ");
int orderAmount = sc.nextInt();
OrderMenuDTO orderMenu = new OrderMenuDTO();
orderMenu.setMenuCode(menucode);
orderMenu.setOrderAmount(orderAmount);
orderMenuList.add(orderMenu); //반복 시마다 주문값 저장
totalOrderPrice += (menuPrice * orderAmount);
System.out.println("계속 주문하시겠습니까?(예/아니오) : ");
sc.nextLine();
boolean isContinue = sc.nextLine().equals("예") ? true : false;
if(!isContinue) break;
} while(true);
for(OrderMenuDTO orderMenu : orderMenuList) { //주문할 메뉴 목록 최종 출력
System.out.println(orderMenu);
}
- View에 해당하는 OrderMenu 클래스에서는 Service 클래스를 private 멤버로 선언한다.
- 메뉴판을 보여주듯 출력 구문을 작성한다.
- 데이터 검색 차원에서 카테고리 코드를 활용할 수 있도록 int categoryCode = 0; 임의의 변수를 생성한다.
java.util.Date orderTime = new java.util.Date(); //java.sql.Date와 구분 위해 패키지명 포함 풀네임
SimpleDateFormat dateFormat = new SimpleDateFormat("yy/MM/dd");
SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm:ss");
String date = dateFormat.format(orderTime);
String time = timeFormat.format(orderTime);
- 여기서 orderTime은 현재 시간으로 설정돼 있다.
- java.sql.Date와 구분 위해 패키지명 포함 풀네임으로 작성한다: java.util.Date
- SimpleDateFormat과 String format() 메소드 통해 날짜와 시간을 원하는 텍스트 형식으로 반환 받을 수 있다.
OrderDTO order = new OrderDTO();
order.setDate(date);
order.setTime(time);
order.setTotalOrderPrice(totalOrderPrice);
order.setOrderMenuList(orderMenuList);
int result = orderService.registOrder(order);
if(result > 0) {
System.out.println("주문에 성공하였습니다.");
} else {
System.out.println("주문에 실패하였습니다.");
}
}
- OrderDTO 객체를 생성하고, 값을 전달한다.
- 최종 결과로서 성공/실패 구문을 출력한다.
-- Application.class
public static void main(String[] args) {
new OrderMenu().displayMenu();
- 사용자에게 보여질 View 클래스로 가정한 OrderMenu의 해당 메소드를 호출해 실행한다.
✅ view 계층을 분리할 수 있다.
✅ view 계층의 의미를 이해할 수 있다.
✅ client가 보게 될 화면과 CRUD의 결과를 출력하는 코드를 작성할 수 있다.
'Database' 카테고리의 다른 글
[JDBC] Controller | MVC 패턴 | CRUD | ResultView (0) | 2022.02.07 |
---|---|
[Oracle/수업 과제 practice] 도서 관리 (0) | 2022.02.06 |
[JDBC] Service | MVC 패턴 | CRUD | Transaction (0) | 2022.02.04 |
[Oracle/2nd Review] Part 3. 오라클 객체 및 권한 (0) | 2022.02.04 |
[JDBC] DAO | MVC 패턴 | CRUD | Query (0) | 2022.02.04 |