본문 바로가기

데브코스/도서 판매 쇼핑몰

API 구현하기(7): 주문하기(2)

MySQL 데이터 삭제하는 방법

 

1) DELETE

DELETE FROM 테이블명 (WHERE 조건);

: 조건이 있으면 조건에 맞는 행만 삭제된다. 

: 조건이 없으면 모든 행이 삭제된다. (테이블은 남아 있음)

 

2) DROP 

DROP TABLE 테이블명; 

: 테이블을 통째로 삭제한다. 

 

3) TRUNCATE

TRUNCATE 테이블명; 

: 모든 행이 삭제된다. (테이블은 남아 있음)

: AUTO INCREMENT 로 설정했던 열의 데이터도 다 지워진다. 


👩🏻‍💻 주문하기 api 구현

const order = async (req, res) => {
  const conn = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'Bookshop',
    port: '3307',// mariadb 포트 번호 3307로 변경했음
    dateStrings: true
  });

  const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } = req.body;

  // delivery 테이블 삽입
  let sql = `INSERT INTO delivery (address, receiver, contact) VALUES (?, ?, ?);`;
  let values = [delivery.address, delivery.receiver, delivery.contact];
  let [results] = await conn.execute(sql, values);
  let delivery_id = results.insertId;

  // orders 테이블 삽입
  sql = `INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id) VALUES (?, ?, ?, ?, ?);`;
  values = [firstBookTitle, totalQuantity, totalPrice, userId, delivery_id];
  [results] = await conn.execute(sql, values);
  let order_id = results.insertId;

  // items 를 가지고, 장바구니에서 book_id, quantity 조회 
  sql = `SELECT book_id, quantity FROM cartItems WHERE id IN (?)`;
  let [orderItems, fields] = await conn.query(sql, [items]);


  // ordered_book 테이블 삽입
  sql = `INSERT INTO ordered_book (order_id, book_id, quantity) VALUES ?;`;
  values = [];
  orderItems.forEach((item) => {
    values.push([order_id, item.book_id, item.quantity]);
  }
  )
  results = await conn.query(sql, [values]);

  let result = await deleteCartItems(conn, items);
  return res.status(StatusCodes.OK).json(result);
};

const deleteCartItems = async (conn, items) => {
  let sql = `DELETE FROM cartItems WHERE id IN (?);`;

  let result = await conn.query(sql, [items]);
  return result;
}

items 에 cartItems(장바구니) 에 저장되어 있는 도서 중에 주문을 원하는 장바구니 번호를 입력한다. 위의 경우에는 장바구니 5,6 번 도서의 결제를 희망하는 경우이다. 

왼) delivery 테이블, 오) orders 테이블

주문이 완료됐을 경우, delivery 테이블에는 주문자 정보가 저장되고, orders 테이블에는 body 에 입력 받은 값으로 주문 정보가 저장된다. 

왼) ordered_book 테이블, 오) cartItems 테이블

ordered_book 테이블에는 주문이 완료된 책 정보가 저장이 되고, 이렇게 주문이 완료된 도서들은 cartItems(장바구니) 테이블에서 삭제되는 것을 확인할 수 있다. 

 

주문 목록 조회

const getOrders = async (req, res) => {
  const conn = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'Bookshop',
    port: '3307',// mariadb 포트 번호 3307로 변경했음
    dateStrings: true
  });

  let sql = `SELECT orders.id, created_at, address, receiver, contact, book_title, total_quantity, total_price
            FROM orders LEFT JOIN delivery 
            ON orders.delivery_id = delivery.id;`;
  let [rows, fields] = await conn.query(sql);
  return res.status(StatusCodes.OK).json(rows);
}

위의 쿼리를 수행하면, 주문 내역과 해당 주문자 정보를 한 번에 확인할 수 있다. 

 

주문 상세 조회

const getOrderDetail = async (req, res) => {
  const {id} = req.params;

  const conn = await mysql.createConnection({
    host: 'localhost',
    user: 'root',
    password: 'root',
    database: 'Bookshop',
    port: '3307',// mariadb 포트 번호 3307로 변경했음
    dateStrings: true
  });

  let sql = `SELECT book_id, title, author, price, quantity
  FROM ordered_book  LEFT JOIN books
  ON ordered_book.book_id = books.id
  WHERE order_id =?;`;

  let [rows, fields] = await conn.query(sql, [id]);
  return res.status(StatusCodes.OK).json(rows);
}

URL 에 order_id (주문 번호) 를 입력하면 해당 주문의 상세 정보(주문한 도서의 정보)를 확인할 수 있다. 


🌟 배운 점

드디어 길고 길었던 주문하기 api 구현이 끝났다. 그동안 했던 것 중에 제일 헷갈리는 부분도 많았고, 아직까지 완전히 이해가 되지 않는 부분도 있는 것 같다.  오늘은 TRUNCATE 문이랑 외래키가 적용되어 있는 테이블을 삭제할 때는 SET FOREIGN_KEY_CHECKS =0 을 사용한다는 것을 새롭게 알게 되었다. 이게 뭔 뜻인지 GPT 에게 물어보니 아래와 같은 뜻이라고 한다.  까먹지 말고 잘 써먹어야겠다. 이번에 주문하기 API 를 구현하면서 비동기 처리 하는 부분이 제일 어려웠던 것 같은데 이 부분을 따로 복습해야겠다. 

더보기

`SET FOREIGN_KEY_CHECKS=0;`는 MySQL이나 MariaDB에서 외래 키 제약을 임시로 비활성화하는 명령어입니다. 외래 키 제약을 끄면 테이블 간의 관계를 무시하고 데이터를 삽입, 삭제, 또는 수정할 수 있습니다. 

이 명령은 주로 다음 상황에서 사용됩니다:
- 데이터를 임포트하거나 수정할 때 외래 키 제약을 신경 쓰지 않기 위해.
- 외래 키가 있는 테이블을 삭제하거나 비우기 위해.

이후에는 `SET FOREIGN_KEY_CHECKS=1;`로 다시 활성화해야 합니다.