1. Java Project 생성

설계
Order
package model;
import lombok.Builder;
import lombok.Data;
// 주문 번호
@Data
public class Order {
private int id;
@Builder
public Order(int id) {
this.id = id;
}
}
OrderOption
package model;
import lombok.Builder;
import lombok.Data;
// 주문 옵션(메뉴)
@Data
public class OrderOption {
private int id;
private String optionName; // 하얀티
private int qty; // 5개
private int totalPrice; // 10000원
private Product product;
private Order order;
@Builder
public OrderOption(int id, String optionName, int qty, int totalPrice, Product product, Order order) {
this.id = id;
this.optionName = optionName;
this.qty = qty;
this.totalPrice = totalPrice;
this.product = product;
this.order = order;
}
}
Product
package model;
import lombok.Builder;
import lombok.Data;
@Data
public class Product {
private int id;
private String name; // 바지
@Builder
public Product(int id, String name) {
this.id = id;
this.name = name;
}
}
ProductOption
package model;
import lombok.Builder;
import lombok.Data;
@Data
public class ProductOption {
private int id;
private String name;
private int price;
private int qty;
private Product product;
@Builder
public ProductOption(int id, String name, int price, int qty, Product product) {
this.id = id;
this.name = name;
this.price = price;
this.qty = qty;
this.product = product;
}
}
2. 문제 풀이
- 1 ~ 4번 문제 : 화면 출력에 알맞은 DTO 제작
package ex01;
import com.google.gson.Gson;
import model.Order;
import model.OrderOption;
import model.Product;
import model.ProductOption;
import java.util.Arrays;
import java.util.List;
public class App1 {
public static void main(String[] args) {
// 판매자 로직
// 1. 상품 2개
Product p1 = new Product(1, "바지");
Product p2 = new Product(2, "티");
List<Product> products = Arrays.asList(p1, p2); // 1번 문제 -> List<Product>를 List<ProductDTO>로 옮기기
// 2. 상품 옵션 4개 생성
ProductOption op1 = new ProductOption(1, "파란바지", 1000, 10, p1);
ProductOption op2 = new ProductOption(2, "빨간바지", 2000, 10, p1);
ProductOption op3 = new ProductOption(3, "노랑티", 1000, 10, p2);
ProductOption op4 = new ProductOption(4, "하얀티", 2000, 10, p2);
List<ProductOption> p1Options = Arrays.asList(op1, op2);
List<ProductOption> p2Options = Arrays.asList(op3, op4); // 2번 문제 -> p2, p2Options -> ProductDetailDTO 로 옮기기
// 구매자 로직
// 3. 구매
Order or1 = new Order(1);
OrderOption orOption1 = new OrderOption(1, "파란바지", 2, 2000, p1, or1);
OrderOption orOption2 = new OrderOption(2, "빨간바지", 2, 4000, p1, or1);
OrderOption orOption3 = new OrderOption(3, "하얀티", 5, 10000, p2, or1);
op1.setQty(op1.getQty() - 2);
op2.setQty(op2.getQty() - 2);
op4.setQty(op4.getQty() - 5);
Order or2 = new Order(2);
OrderOption orOption4 = new OrderOption(4, "노랑티", 7, 7000, p2, or2);
op3.setQty(op3.getQty() - 7);
// 4. 상품 출력
// 1번 문제 : 상품 목록 화면
// List<Product> -> List<ProductDTO>
// 2번 문제 : 상품 상세 화면 (p2)
// Product(p2, p2Options) -> ProductDetail
// 3번 문제 : 주문 확인 상세 화면 (or2)
// 틀렸음 : DTO 담기
// 4번 문제 : 주문 확인 상세 화면 (or1)
// (orOption1, orOption2), (orOption3) -> OrderDetailDTO
}
}
해답
1번 문제
- Product를 저장하는 DTO : 깊은 복사
package ex01;
import lombok.Data;
import model.Product;
@Data
public class ProductDTO {
private int id;
private String name;
public ProductDTO(Product product) {
this.id = product.getId();
this.name = product.getName();
}
}
List<ProductDTO> productsDTO = Arrays.asList(new ProductDTO(p1), new ProductDTO(p2));
- 출력은 GSON 활용 : JSON 형태로 결과를 출력
Gson gson = new Gson();
String ex01 = gson.toJson(productsDTO);
System.out.println(ex01);

2번 문제
- 하나의 DTO 안에 여러 객체가 저장되어야 함
package ex01;
import lombok.Data;
import model.Product;
import model.ProductOption;
import java.util.ArrayList;
import java.util.List;
@Data
public class ProductDetailDTO {
private Integer productId;
private String productName;
List<ProductOptionDTO> options = new ArrayList<>();
public ProductDetailDTO(Product p, List<ProductOption> options) {
this.productId = p.getId();
this.productName = p.getName();
for (ProductOption op : options) {
this.options.add(new ProductOptionDTO(op));
}
}
@Data
public class ProductOptionDTO {
private int optionId;
private String optionName;
private int optionPrice;
private int optionQty;
public ProductOptionDTO(ProductOption op) {
this.optionId = op.getId();
this.optionName = op.getName();
this.optionPrice = op.getPrice();
this.optionQty = op.getQty();
}
}
}
ProductDetailDTO productDetailDTO = new ProductDetailDTO(p2, p2Options);
String ex02 = gson.toJson(productDetailDTO);
System.out.println(ex02);

3번 문제
- Order와 Product의 구분을 확실히 해야 함
package ex01;
import lombok.Data;
import model.OrderOption;
// 3번 문제만을 위한 DTO
@Data
public class TempDTO {
private Integer orderId;
private Integer productId;
private Integer orderOptionId;
private String orderOptionName;
private Integer orderOptionQty;
private Integer totalPrice;
public TempDTO(OrderOption orderOption) {
this.orderId = orderOption.getOrder().getId();
this.productId = orderOption.getProduct().getId(); // Lazy Loading (조인 안했다면)
this.orderOptionId = orderOption.getId();
this.orderOptionName = orderOption.getOptionName();
this.orderOptionQty = orderOption.getQty();
this.totalPrice = orderOption.getTotalPrice();
}
}
TempDTO tempDTO = new TempDTO(orOption4);
String ex03 = gson.toJson(tempDTO);
System.out.println(ex03);

4번 문제
- DTO → DTO → DTO의 연쇄 작용
package ex01;
import lombok.Data;
import model.OrderOption;
import java.util.ArrayList;
import java.util.List;
@Data
public class OrderDetailDTO {
private Integer orderId;
private List<X> products;
private Integer totalPrice = 0;
public OrderDetailDTO(List<OrderOption> orderOptions) { // p1(orOption1, orOption2), p2(orOption3)
System.out.println("*");
this.orderId = orderOptions.getFirst().getOrder().getId();
List<OrderOption> op1s = new ArrayList<>();
op1s.add(orderOptions.get(0));
op1s.add(orderOptions.get(1));
List<OrderOption> op2s = new ArrayList<>();
op2s.add(orderOptions.get(2));
X x1 = new X(op1s);
X x2 = new X(op2s);
List<X> xList = new ArrayList<>();
xList.add(x1);
xList.add(x2);
this.products = xList;
for (OrderOption op : orderOptions) {
this.totalPrice += op.getTotalPrice();
}
}
@Data
public class X {
private Integer productId;
private List<Y> orderOptions;
public X(List<OrderOption> orderOptions) {
System.out.println("**");
this.productId = orderOptions.getFirst().getProduct().getId();
List<Y> yList = new ArrayList<>();
for (OrderOption orderOption : orderOptions) {
yList.add(new Y(orderOption));
}
this.orderOptions = yList;
}
@Data
public class Y {
private Integer orderOptionId;
private String orderOptionName;
private Integer orderOptionQty;
private Integer orderOptionTotalPrice;
public Y(OrderOption orderOption) {
System.out.println("***");
this.orderOptionId = orderOption.getId();
this.orderOptionName = orderOption.getOptionName();
this.orderOptionQty = orderOption.getQty();
this.orderOptionTotalPrice = orderOption.getTotalPrice();
}
}
}
}
List<OrderOption> or1Options = Arrays.asList(orOption1, orOption2, orOption3);
OrderDetailDTO orderDetailDTO = new OrderDetailDTO(or1Options);
String ex04 = gson.toJson(orderDetailDTO);
System.out.println(ex04);

4번 문제 풀이 보완
- 리스트 동적 제작
- 멤버 동적 삽입

package ex01;
import lombok.Data;
import model.OrderOption;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@Data
public class OrderDetailDTO {
private int orderId;
private List<ProductDTO> products = new ArrayList<>();
private int sumPrice;
public OrderDetailDTO(List<OrderOption> orderOptions) {
this.orderId = orderOptions.getFirst().getId();
// 중복이 제거된 상품 ids + 전체금액 계산
Set<Integer> productIds = new HashSet<>();
for (OrderOption orderOption : orderOptions) {
productIds.add(orderOption.getProduct().getId());
this.sumPrice += orderOption.getTotalPrice();
}
// 상품별 주문한 상품옵션 만들기
for (Integer productId : productIds) {
List<OrderOption> selectedOptions = new ArrayList<>();
for (OrderOption orderOption : orderOptions) {
if (productId == orderOption.getProduct().getId()) {
selectedOptions.add(orderOption);
}
}
ProductDTO productDTO = new ProductDTO(productId, selectedOptions);
this.products.add(productDTO);
}
}
@Data
class ProductDTO {
private int productId;
private List<OrderOptionDTO> orderOptions = new ArrayList<>();
public ProductDTO(int productId, List<OrderOption> orderOptions) {
this.productId = productId;
for (OrderOption orderOption : orderOptions) {
this.orderOptions.add(new OrderOptionDTO(orderOption));
}
}
@Data
class OrderOptionDTO {
private int orderOptionId;
private String orderOptionName;
private int orderQty;
private int orderTotalPrice;
public OrderOptionDTO(OrderOption orderOption) {
this.orderOptionId = orderOption.getId();
this.orderOptionName = orderOption.getOptionName();
this.orderQty = orderOption.getQty();
this.orderTotalPrice = orderOption.getTotalPrice();
}
}
}
}
- 결과는 동일
Share article