오늘은 몰랐으면 내일은 알면 된다

2022-11-15 (2) 클래스 설계 / 예제 실습 본문

Java/JAVA 개발자 양성과정

2022-11-15 (2) 클래스 설계 / 예제 실습

마스터피쓰 2022. 11. 15. 14:56

order_id는 주문한 고객의 id이다. order_info 와 함께 주문자의 정보를 JOIN으로 가지고 오려면, OrderInfo 클래스가 Customer 테이블의 정보를 받아올 수 있어야 한다.

따라서 Customer 테이블의 정보를 담을 수 있는 Customer 객체를 가지고 있어야 한다. 그렇지 않으면 SELECT를 두번 사용하여 order info, customer의 정보를 각각 가지고 와야할 것이다.

has a 관계는 언제 가져야 하는가?

예를들어 아래와 같이, 주문 상세 정보는 주문 기본정보를 확인할 때 함께 확인이 될 것이다. 그리고 하나의 주문 기본정보는 여러개의 주문 상세 정보를 가지고 있을 것이다.(일대다 관계)

이러한 테이블 관계를 그대로 클래스 관계로 옮기면 된다.

order_info의 정보를 가지는 OrderInfo 클래스는 여러개의 order_line 정보를 가질 것이므로 필드에 List<OrderLine> 을 가져야 할 것 이다.

또한, 주문 상세를 조회할 때, 누가 주문했는지에 대한 정보도 함께 조회되어야 하므로 고객의 정보를 담을 수 있는 Customer도 필드로 가지고 있어야 한다.

 

 

예제) 다음의 결과가 나오도록 코드를 작성하자.

콘솔 결과
select 결과

 

Main Method

public static void main(String[] args) {
		OrderRepositoryOracle repository = new OrderRepositoryOracle();
		//--주문 검색 테스트
		try {
			List<OrderInfo> infos = repository.selectById("id1");
			for(OrderInfo info: infos) {
				int orderNo = info.getOrderNo();
				String orderId = info.getOrderC().getId();
				Date orderDt = info.getOrderDt();
				System.out.println("주문번호 : " + orderNo);				
				System.out.println("주문일자 : " + orderDt);
				List<OrderLine> lines = info.getLines();
				System.out.println("주문상품번호\t주문상품명\t주문상품가격\t주문수량");
				for(OrderLine line: lines) {
					Product p = line.getOrderP();
					String prodNo = p.getProdNo();
					String prodName = p.getProdName();
					int prodPrice = p.getProdPrice();
					int orderQuantity = line.getOrderQuantity();
					System.out.println(prodNo+"\t" + prodName +"\t"+ prodPrice +"\t"+ orderQuantity);
				}
				System.out.println("-----------------------------------------");
			}
		} catch (FindException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}


OrderRepositoryOracle.java

package com.my.repository;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.my.exception.AddException;
import com.my.exception.FindException;
import com.my.vo.Customer;
import com.my.vo.OrderInfo;
import com.my.vo.OrderLine;
import com.my.vo.Product;

public class OrderRepositoryOracle implements OrderRepository {

	private void insertInfo(Connection conn, OrderInfo info) throws Exception {
		PreparedStatement pstmt = null;
		String insertInfoSQL = "INSERT INTO order_info(order_no, order_id, order_dt) "
							+ "VALUES(order_seq.NEXTVAL,?,SYSDATE)";
		try {
			pstmt = conn.prepareStatement(insertInfoSQL);
			pstmt.setString(1, info.getOrderC().getId());
			pstmt.executeUpdate();
		} finally {
			Myconnection.close(null, pstmt, null);
		}
		
	}
	private void insertLines(Connection conn, List<OrderLine> lines) throws Exception {
		PreparedStatement pstmt = null;
		String insertLineSQL = "INSERT INTO order_line(order_no, order_prod_no, order_quantity) "
							+ "VALUES(order_seq.CURRVAL, ?, ?)";
		try {
			pstmt = conn.prepareStatement(insertLineSQL);
			for(OrderLine line : lines) {
				pstmt.setString(1, line.getOrderP().getProdNo());
				pstmt.setInt(2, line.getOrderQuantity());
				pstmt.executeUpdate();
			}
		} finally {
			Myconnection.close(null, pstmt, null);
		}
	}
	@Override
	public void insert(OrderInfo info) throws AddException {
		Connection conn = null;
		
		try {
			conn = Myconnection.connect();
			
			//JDBC는 기본 오토커밋 -> false로 변경
			conn.setAutoCommit(false);
			//주문기본정보 추가
			insertInfo(conn, info);
			//주문상세정보 추가
			insertLines(conn, info.getLines());
			
			conn.commit();
			
		} catch (Exception e) {
			try {
				conn.rollback();
			} catch(SQLException e1) {
				
			}
			e.printStackTrace();
			throw new AddException(e.getMessage());
		} finally {
			Myconnection.close(conn, null, null);
		}
	}
	@Override
	public List<OrderInfo> selectById(String orderId) throws FindException {
		Connection conn = null;
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		List<OrderInfo> infoList = new ArrayList<>();
		try {
			conn = Myconnection.connect();
			
			String selectSQL = "SELECT i.order_no, i.order_id, i.order_dt,\r\n"
					+ "        l.order_prod_no, l.order_quantity,\r\n"
					+ "        p.prod_name, p.prod_price, p.prod_info\r\n"
					+ "FROM order_info i\r\n"
					+ "JOIN order_line l ON (i.order_no = l.order_no)\r\n"
					+ "JOIN product p ON (l.order_prod_no = p.prod_no)\r\n"
					+ "WHERE i.order_id = ?";
			pstmt = conn.prepareStatement(selectSQL);
			pstmt.setString(1, orderId);
			rs = pstmt.executeQuery();
			
			List<OrderLine> lineList = null;
			int prevOrderNo = 0;
			while(rs.next()) {
				OrderLine line = new OrderLine();
				int orderNo = rs.getInt("order_no");
				line.setOrderNo(orderNo);
				line.setOrderQuantity(rs.getInt("order_quantity"));
				
				Product p = new Product();
				p.setProdNo(rs.getString("order_prod_no"));
				p.setProdName(rs.getString("prod_name"));
				p.setProdPrice(rs.getInt("prod_price"));
				
				line.setOrderP(p);
				if(prevOrderNo != orderNo) {
					prevOrderNo = orderNo;
					OrderInfo info = new OrderInfo();
					info.setOrderNo(orderNo);
					info.setOrderDt(rs.getDate("order_dt"));
					info.setOrderC(new Customer(rs.getString("order_id"), null, null));
					lineList = new ArrayList<>();
					lineList.add(line);
					info.setLines(lineList);
					infoList.add(info);
				} else  {
					lineList.add(line);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		
		return infoList;
	}
}