CREATE TABLE IF NOT EXISTS MANAGER
(
    id bigint primary key,
    name varchar(100) not null,
    student_code varchar(100) not null,
    constraint manager_fk_student_code foreign key(student_code) references STUDENT(student_code)
);

 

문제 2

ALTER, MODIFY를 이용하여 MANAGER 테이블의 id 컬럼에 AUTO_INCREMENT 기능을 부여하세요.

ALTER TABLE MANAGER MODIFY COLUMN id bigint NOT NULL AUTO_INCREMENT;

 

문제 3

INSERT를 이용하여 수강생 s1, s2, s3, s4, s5를 관리하는 managerA와 s6, s7, s8, s9를 관리하는 managerB를 추가하세요.

AUTO_INCREMENT 기능을 활용하세요.

INSERT INTO MANAGER(name, student_code) VALUES ('managerA', 's1');
INSERT INTO MANAGER(name, student_code) VALUES ('managerA', 's2');
INSERT INTO MANAGER(name, student_code) VALUES ('managerA', 's3');
INSERT INTO MANAGER(name, student_code) VALUES ('managerA', 's4');
INSERT INTO MANAGER(name, student_code) VALUES ('managerA', 's5');

INSERT INTO MANAGER(name, student_code) VALUES ('managerB', 's6');
INSERT INTO MANAGER(name, student_code) VALUES ('managerB', 's7');
INSERT INTO MANAGER(name, student_code) VALUES ('managerB', 's8');
INSERT INTO MANAGER(name, student_code) VALUES ('managerB', 's9');

 

문제 4

JOIN을 사용하여 managerA가 관리하는 수강생들의 이름과 시험 주차 별 성적을 가져오세요.

SELECT s.name, e.exam_seq, e.score
FROM MANAGER m JOIN STUDENT S on S.student_code = m.student_code
JOIN EXAM E on S.student_code = E.student_code
WHERE m.name = 'managerA';

 

문제 5

STUDENT 테이블에서 s1 수강생을 삭제했을 때 EXAM에 있는 s1수강생의 시험성적과 MANAGER의 managerA가 관리하는 수강생 목록에 자동으로 삭제될 수 있도록 하세요.

  • ALTER, DROP, MODIFY, CASCADE 를 사용하여 EXAM, MANAGER 테이블을 수정합니다.
ALTER TABLE EXAM DROP CONSTRAINT exam_fk_student_code;
ALTER TABLE EXAM ADD CONSTRAINT exam_fk_student_code FOREIGN KEY(student_code) REFERENCES STUDENT(student_code) ON DELETE CASCADE;
ALTER TABLE MANAGER DROP CONSTRAINT manager_fk_student_code;
ALTER TABLE MANAGER ADD CONSTRAINT manager_fk_student_code FOREIGN KEY(student_code) REFERENCES STUDENT(student_code) ON DELETE CASCADE;

DELETE FROM STUDENT WHERE student_code = 's1';

기존 제약조건을 지우고 ON DELETE CASCADE 옵션을 걸어 다시 설정해준다.

'TIL > WEEK5' 카테고리의 다른 글

SpringBoot의 JPA  (0) 2023.06.15
IoC와 DI  (1) 2023.06.14
Spring 입문 1주차  (0) 2023.06.12

Gradle

빌드 자동화 시스템

빌드란 소스코드를 실행 가능한 결과물로 만드는 일련의 과정

java 소스 코드 ➡️ jar 파일

 

 

Spring MVC

 

Model

  • 데이터와 비즈니스 로직을 담당
  • 데이터 베이스와 연동해 데이터를 불러오고 저장하는 작업을 수행

View

  • 사용자 인터페이스를 담당
  • 사용자가 보는 화면과 버튼, 폼 등을 디자인하고 구현 (html)

Controller

  • Model과 View 사이의 상호작용을 조정하고 제어
  • 사용자의 입력을 받아 Model에 전달하고, Model의 결과를 바탕으로 View를 업데이트

 

 

 

데이터를 Client에 반환하는 방법

  • JSON 데이터 반환하는 방법

템플릿 엔진이 적용된 SpringBoot에서는 Controller에서 문자열을 반환하면 templates 폴더에서 해당 문자열의 .html 파일을 찾아서 반환한다.

   @GetMapping("/html/templates")
    public String htmlTemplates() {
        return "hello";
    }

 

따라서 html 파일이 아닌 JSON 데이터를 브라우저에 반환하고 싶다면 해당 메서드에 @ResponseBody 애너테이션을 추가해줘야 한다.

@GetMapping("/response/json/string")
@ResponseBody
public String helloStringJson() {
    return "{\"name\":\"Robbie\",\"age\":95}";
}

+ "(큰 따옴표)는 그냥 쓰면 출력이 안되므로 앞에 \을 붙여준다.

 

Spring에서 자동으로 객체를 JSON으로 변환해 준다.

@GetMapping("/response/json/class")
@ResponseBody
public Star helloClassJson() {
    return new Star("Robbie", 95);
}

http://localhost:8080/response/json/class

  • @RestController

@RestController를 사용하면 해당 클래스의 모든 메서드에 @ResponseBody 애너테이션이 추가되는 효과를 부여할 수 있다.

@RestController = @Controller + @ResponseBody

 

 

 

Serialize(직렬화)

Object ➡️ JSON

@Test
@DisplayName("Object To JSON : get Method 필요")
void test1() throws JsonProcessingException {
    Star star = new Star("Robbie", 95);

    ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper
    String json = objectMapper.writeValueAsString(star);

    System.out.println("json = " + json);
}

Object를 JSON 타입의 String으로 변환하기 위해서는 해당 Object에 get Method가 필요하다.

 

Deserialize(역직렬화)

JSON ➡️ Object

@Test
@DisplayName("JSON To Object : 기본 생성자 & (get OR set) Method 필요")
void test2() throws JsonProcessingException {
    String json = "{\"name\":\"Robbie\",\"age\":95}"; // JSON 타입의 String

    ObjectMapper objectMapper = new ObjectMapper(); // Jackson 라이브러리의 ObjectMapper

    Star star = objectMapper.readValue(json, Star.class);
    System.out.println("star.getName() = " + star.getName());
}

JSON 타입의 String을 Object로 변환하기 위해서는 해당 Object에 기본 생성자get 혹은 set 메서드가 필요하다.

'TIL > WEEK5' 카테고리의 다른 글

SpringBoot의 JPA  (0) 2023.06.15
IoC와 DI  (1) 2023.06.14
1주차 숙제  (0) 2023.06.13

1. compareTo() 메서드를 오버라이딩 해준다. 최신순(내림차순)으로 정렬하기 위해 리턴 값에 -1을 곱해줬다.

public class CompletedOrder extends Order implements Comparable<CompletedOrder> {
    String completiontime;

    CompletedOrder(){
    }

    CompletedOrder(Order order){
        super(order.orderNum, order.orderList, order.totalPrice, order.time, order.request);
        this.completiontime = getTime();
    }

    @Override
    public String toString() {
        return "\n1. 대기번호 : " + this.orderNum + "\n2. 주문 상품 목록 : " + this.orderList +"\n3. 주문 총 가격 : " + this.totalPrice + "W\n4. 요청사항 : " + this.request + "\n5. 주문 일시 : " + this.time + "\n6. 완료 주문 일시 : " +this.completiontime+ "\n";
    }

    @Override
    public int compareTo(CompletedOrder o) {
        return this.completiontime.compareTo(o.completiontime) * -1; // 최신순 정렬
    }
}

 

2. sort 메서드로 정렬해 준다. 이때 정렬 기준에 오버라이딩한 compareTo를 넣어준다.

    public void printRecentOrder(){
        System.out.println("[ 최근 완료된 주문 ]");
        
        Collections.sort(completedOrders, CompletedOrder::compareTo); // 주문 완료 처리된 순서대로 정렬

        int SIZE = completedOrders.size();
        if(SIZE >= 3){
            for (int i = 0; i <3; i++){
                System.out.println(completedOrders.get(i));
            }
        } else {
            for (CompletedOrder o : completedOrders){
                System.out.println(o);
            }
        }
    }

 

'TIL > WEEK4' 카테고리의 다른 글

팀 과제 키오스크 관리 프로젝트  (0) 2023.06.07

지난번 개인 과제 키오스크에서 기능을 추가하는 팀 프로젝트를 진행했다.

 

과제에서 요구한 추가 기능은 다음과 같다.

손님이 주문할 때 요청사항을 적는 기능

  • (개선) 주문 화면

         주문 시 요청사항 메시지를 입력할 수 있습니다. (20자 제한)

  • (신규) 주문 현황

          맨 위에 완료된 최근주문 3개를 출력한다.

          그 아래에 대기 중인 모든 주문 목록을 출력한다.

 

 

가게 주인이 주문 현황과 메뉴 목록을 추가, 삭제할 수 있도록 하는 기능

          0. 메인 메뉴

    • 메인 메뉴에서 아래 기능을 실행한다.
      • “1. 대기주문 목록”
      • “2. 완료주문 목록”
      • “3. 상품 생성”
      • “4. 상품 삭제”
    1. 대기주문 목록
    • 주문이 완료되어 처리 대기 중인 주문을 조회하고 완료처리 할 수 있다.
    • 주문 데이터 형식은 아래와 같다.
      1. 대기 번호
      2. 주문 상품 목록
      3. 주문 총 가격
      4. 요청 사항
      5. 주문 일시
      6. 날짜는 ISO 8601 형식으로 조합된 UTC 날짜 및 시간 예) 2016-10-27T 17:13:40+00:00

            2. 완료 주문 목록

      • 완료처리 했던 주문들을 모두 조회할 수 있다.
      • **[ 완료주문 데이터 ]**는 **[ 주문 데이터 ]**에 완료 일시를 추가로 가진다.
      • [ 완료주문 데이터 ]
        1. 대기 번호
        2. 주문 상품 목록
        3. 주문 총 가격
        4. 주문 일시
        5. 요청 사항
        6. 완료주문 일시
        7. 날짜는 ISO 8601 형식으로 조합된 UTC 날짜 및 시간 예) 2016-10-27T 17:13:40+00:00

               3. 상품 생성

      • 새로운 상품정보(메뉴, 이름, 설명, 가격)를 입력하여 생성할 수 있다.
      • 기존에 없는 메뉴라면 신규로 생성해 준다.
      • 새로 생성된 메뉴와 상품은 각각 유일한 메뉴 ID, 상품 ID 식별자를 가진다.

                4. 상품 삭제

      • 상품 ID를 가지고 기존 상품정보를 삭제할 수 있다.
      • 삭제이전에 주문된 주문정보에서는 삭제되지 않는다.

 

 

 

 

 

대기주문 목록을 담을 Order 클래스

인스턴스를 생성할 때 자동으로 주문일시(time)에 현재 시각을 넣을 수 있게 매개변수로 time을 받지 않는 생성자를 만들어줬다.

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class Order {
    int orderNum;
    String orderList;
    String time;
    double totalPrice;
    String request;

    Order(){}
    Order(int orderNum, String orderList, double totalPrice, String time, String request){
        this.orderNum = orderNum;
        this.orderList = orderList;
        this.totalPrice = totalPrice;
        this.time = time;
        this.request = request;
    }

    Order(int orderNum, String orderList, double totalPrice, String request){
        this.orderNum = orderNum;
        this.orderList = orderList;
        this.totalPrice = totalPrice;
        this.request = request;
        this.time = getTime();
    }

    public String getTime() {
        LocalDateTime now = LocalDateTime.now();
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
        return now.format(dateTimeFormatter);
    }

    @Override
    public String toString() {
        return "\n1. 대기번호 : " + this.orderNum + "\n2. 주문 상품 목록 : " + this.orderList +"\n3. 주문 총 가격 : " + this.totalPrice +"W\n4. 요청사항 : " + this.request + "\n5. 주문 일시 : " + this.time + "\n";
    }

}

 

 

 

주문 시 요청사항(request)을 손님에게 입력받은 뒤 장바구니(cart)에 담겨 있는 상품명들을 문자열로 연결해서(orderlist) 대기주문 목록(orders)에 넣어줬다. 주문번호와 총가격은 기존 프로젝트에 이미 있어서 그대로 가져왔다.

    private List<Item> cart;
    private List<Order> orders;
    
    
    public void addToWaiting(List<Item> cart){
        Scanner sc = new Scanner(System.in);
        System.out.println("요청 사항을 입력해주세요.");
        String request = sc.nextLine();

        String orderList = "";
        for(Item a : cart){
            orderList += a.name + ", ";
        }
        orderList = orderList.substring(0, orderList.length() - 2); // 맨 끝 , 제거
        orders.add(new Order(orderNumber, orderList, totalPrice, request));

    }

 

 

 

완료 주문 데이터는 대기 주문 데이터를 상속받아 주문 완료 일시(completiontime) 변수를 추가해 줬다. 또 완료 주문 목록을 최신순으로 정렬하기 위해 주문 완료 일시(completiontime)를 기준으로 비교하도록 compareTo를 오버라이딩 해줬다.

public class CompletedOrder extends Order implements Comparable<CompletedOrder> {
    String completiontime;

    CompletedOrder(){
    }

    CompletedOrder(Order order){
        super(order.orderNum, order.orderList, order.totalPrice, order.time, order.request);
        this.completiontime = getTime();
    }

    @Override
    public String toString() {
        return "\n1. 완료번호 : " + this.orderNum + "\n2. 주문 상품 목록 : " + this.orderList +"\n3. 주문 총 가격 : " + this.totalPrice + "W\n4. 요청사항 : " + this.request + "\n5. 주문 일시 : " + this.time + "\n6. 완료 주문 일시 : " +this.completiontime+ "\n";
    }
    @Override
    public int compareTo(CompletedOrder order) {
        return this.time.compareTo(order.completiontime);
    }


}

 

 

 

관리자가 완료처리할 대기주문 번호(idx)를 고르면 선택한 주문 데이터(co)를 완료 주문 리스트(completedOrders)에 추가하고 대기주문 목록(orders)에서 삭제했다.

    public void CompletedOrder(int idx){
        Order co = getOrder(idx);
        orders.remove(idx);
        completedOrders.add(new CompletedOrder(co));
    }

 

 

 

완료된 최근주문 3개를 출력하도록 내림차순으로 정렬한 뒤, 완료 주문 목록의 크기가 3 이상이면 세 개만 출력되게 하고 그 미만이면 전부 출력되게 했다.

private List<CompletedOrder> completedOrders;


public void printRecentOrder(){
        completedOrders.sort(Collections.reverseOrder());
        int SIZE = completedOrders.size();
        if(SIZE >= 3){
            for (int i = 0; i <3; i++){
                System.out.println(completedOrders.get(i));
            }
        } else {
            for (CompletedOrder o : completedOrders){
                System.out.println(o);
            }
        }
    }

 

 

 

그 아래 대기 중인 주문 모두를 출력하는 메서드는 다음과 같이 작성했다.

    public void printWaiting() {
        int SIZE = orders.size();
        System.out.println("\n대기주문 "+SIZE+"개\n");
        for (Order order : orders){
            System.out.println(order);
        }
    }

 

'TIL > WEEK4' 카테고리의 다른 글

객체 내 시간 요소 순으로 정렬하기  (0) 2023.06.08

아쉬운 점

주문 번호를 출력하려면 순서가 있어야 된다고 생각해서 ArrayList를 이용해 구현했는데 다른 컬렉션을 써봤으면 어땠을까 싶다. 과제의 필수 요구사항은 구현했으나 선택 요구사항은 구현하지 못했다. 내가 시도했던 선택 요구사항은 주문개수 기능 추가였는데,

위와 같이 유저가 장바구니에 같은 메뉴를 담으면 개수를 늘려서 출력하는 기능이다.

근데 ArrayList에서 중복 값을 찾으려면 Set이나 Map으로 변환을 해야 된다고 한다. 그래서 아예 처음부터 Map으로 설계했으면 어땠을까 싶다. 아직 Map이나 Set은 낯설어서 강의를 좀 더 듣고 연습도 해봐야겠다.

'TIL > WEEK3' 카테고리의 다른 글

예외처리  (0) 2023.05.31
개인과제 키오스크  (0) 2023.05.30

오늘의 삽질

오늘은 예외처리 강의를 들었는데 마침 지금 진행 중인 개인과제의 키오스크가 InputMismatchException을 다뤄보기 좋은 예제라 내가 짠 키오스크 코드로 예외처리에 도전해 봤다. 익셉션을 캐치하는 것까지는 잘 됐는데 catch 블락을 빠져나가면 프로그램을 그냥 끝내지 말고 다시 처음부터 실행시키고 싶어서 continue를 했더니 메인페이지에서 입력값은 안 받고 무한 루프되는 오류가 생겼다.. 

근데 마침 자바의 정석 8-7 연습문제가 이와 비슷한 케이스라 이걸로 먼저 연습해 보고 다시 도전해 봐야겠다.

 

연습문제 8-7

1~100 사이의 숫자를 맞추는 프로그램을 작성하시오. 예외처리를 해서 숫자가 아닌 값을 입력했을 때는 다시 입력을 받도록 하시오.

import java.util.Scanner;

public class Main {
    public static void main(String[] args) {
        int answer = (int) (Math.random() * 100) + 1;
        int input = 0;
        int count = 0;

        do {
            count++;
            System.out.println("1과 100 사이의 값을 입력하세요 : ");

            // input = new Scanner(System.in).nextInt();
            try {
                Scanner sc = new Scanner(System.in);
                input = sc.nextInt();
            } catch (Exception e) {
                System.out.println("숫자를 입력해주세요.");
                continue;
            }

            if (answer > input) {
                System.out.println("더 큰 수를 입력하세요.");
            } else if (answer < input) {
                System.out.println("더 작은 수를 입력하세요.");
            } else {
                System.out.println("맞췄습니다.");
                System.out.println("시도 횟수는 " + count + "번입니다.");
                break;
            }

        } while (true);


    }
}

 

'TIL > WEEK3' 카테고리의 다른 글

개인과제 키오스크 완성  (0) 2023.06.01
개인과제 키오스크  (0) 2023.05.30

키오스크의 필수 기능(메뉴 선택, 취소, 장바구니에 넣기, 주문 취소, 주문완료)은 전부 구현했다.

 

오늘의 삽질!

 

1.  장바구니 상품 총 가격 오류

문제점 : 장바구니를 확인하고 다시 메인 메뉴로 돌아갔다 다시 장바구니 확인 창으로 돌아오면 장바구니에 넣어놓은 상품의 총가격이 두 배가 되는 오류가 발생

해결방안 : 총가격을 Order 클래스의 인스턴스 변수로 선언해놨더니 장바구니 확인 화면에서 나갔다가 다시 들어올 때마다 가격이 계속 더해져서 그런 오류가 발생했던 것 같다. 총가격을 지역변수로 바꾸고 메서드 첫줄에서 0으로 초기화 시켜줬더니 제대로 동작했다.

    public double getTotalPrice() {
        double totalPrice = 0.0;
        for(int i=0 ; i < order.size(); i++){
            totalPrice += order.get(i).price;
        }
        return totalPrice;
    }

 

2.  다중 중첩문의 continue

또 조건문과 반복문이 여러겹으로 중첩될 때 continue를 어떻게 써야 할지 잘 모르겠다. 사용자가 주문을 취소했을 때, 안쪽 루프에서 제일 바깥 루프로 가려고 메인 메뉴 루프에 라벨을 달고 continue 했더니 아래와 같은 경고가 떴다.

그래서 라벨을 지우고 그냥 컨틴뉴 해봤더니 이번엔 컨티뉴 자체가 불필요하단 경고창이 떴다;

아직 예외 처리부분 강의를 못 들었는데 아마 예외처리 강의에서 이런 부분도 다루지 않을까 싶다. 내일은 코딩보다 강의를 좀 들어봐야겠다.

 

 

'TIL > WEEK3' 카테고리의 다른 글

개인과제 키오스크 완성  (0) 2023.06.01
예외처리  (0) 2023.05.31

우리 동네 맛집 '똣똣카페'의 키오스크를 구현해볼 예정이다.

똣똣카페의 메뉴는 크게 반미, 로띠, 음료로 나뉘는데 반미는 고수 추가 옵션이 있고, 음료는 핫/아이스 옵션이 있으며 로띠는 따로 추가 옵션이 없다. 그러므로 추가 옵션이 없는 가장 기본적인 로띠 메뉴로 일단 코드를 짜봤다.

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
import java.util.SortedMap;

class Menu {

    String name;
    int price;

    Menu(String name, int price) {
        this.name = name;
        this.price = price;
    }

}


public class Main{
    public static void main(String[] args) {
        List<Menu> roti = new ArrayList<>();
        roti.add(new Menu("누텔라 바나나 로띠", 7800));
        roti.add(new Menu("계란 바나나 로띠", 7800));
        roti.add(new Menu("카야 로띠", 7800));

        System.out.println("메뉴를 선택해 주세요.");

        for(int i = 0; i < roti.size(); i++){
            int num = i + 1;
            System.out.println(num + ". " + roti.get(i).name + "   | " + roti.get(i).price + "원");
        }

        Scanner sc = new Scanner(System.in);
        int select = sc.nextInt();
        int orderNum = select - 1;

        System.out.println(roti.get(orderNum).name + " 1개 총 " + roti.get(orderNum).price + "원 주문하시겠습니까?");


    }

}

메뉴 클래스를 상속받는 클래스로 상품 클래스를 따로 구현해봐야겠다.

'WIL' 카테고리의 다른 글

AOP란?  (0) 2023.07.16
WEEK1  (0) 2023.05.21

+ Recent posts