백엔드 실습(11)

wltjd1688·2025년 3월 20일

풀사이클

목록 보기
38/74

오늘은 이전에 다 구현하지 못한 주문 로직을 끝낼 수 있었다.

MySQL 테이터 삭제하는 방법

크게 3가지 방법이 있음

  1. DELETE

    DELETE FROM 테이블명 (WHERE 조건);
  • 조건이 있으면 맞는 행만 삭제됨, 조건이 없으면 모든 행이 삭제됨(테이블은 당연히 남아있음)
  • 말 그대로 데이터를 삭제하는것
  • auto increment는 초기화 되지 않음
  1. DROP

    DROP TABLE 테이블명;
  • 테이블을 통째로 삭제하는 것
  • DELETE랑 TRUNCATE와 목적이 다른느낌

3) TRUNCATE

TRUNCATE 테이블 명;
  • 모든 행이 삭제됩니다.(테이블은 남아있음)
  • 행의 삭제보다는 초기화에 더 어울림
  • auto increment도 1부터 다시 시작해줌

외래키 제약 해체

TRUNCATE로 초기화 했을 때, 해당 테이블에서 Foreign key를 가지고 있는걸 삭제하기 위해서 다음과 같은 명령어를 사용할 수 있다.

SET FOREIGN_KEY_CHECKS = 0;

삭제후 다시 1로 설정하여, 원상복구할 수 있다.

그래서 order와 같이 여러 foreign_key가 연결된 테이블을 초기호할때는 다음의 순서로 작성해주는게 좋다.

SET FOREIGN_KEY_CHECKS = 0;
TRUNCATE orderBooks;
TRUNCATE delivery;
TRUNCATE orders;
SET FOREIGN_KEY_CHECKS = 1;

주문하기 insert

MySQL2에서 SQL 쿼리를 실행하는 방법으로 2가지가 있다.

  • .query()

    • 실행했을때 결과값이 [result, undefined]형태로 출력된다. 그래서 result만 출력할려면 result[0]과 같이 수정하는게 좋다.
    • 단발성 쿼리나 동적으로 SQL을 구성할 때 유용하다.(실핼할 때 마다 파싱작업이 이루어진다.)
      let result = await db.query(sql, values);
      /** 
          [{
          ...
          },
          undefined
          ]
      */
  • .execute()

    • 실행했을때 결과값이 [result]로 깔끔하게 반환된다.
    • 자주 실행되는 쿼리에 대해서 캐싱이 이뤄져, 로그인, 주민입력등에 유용하다.
      let result = await db.execute(sql, values);
      /**
          [{
          ...
          }]
      */

db를 연결하는 createConnectioncreatePool의 차이

  • createConnection
    • 하나의 고정된 연결을 생성하여, 애플리케이션이 종료되거나 연결이 닫힐 때까지 해당 연결을 재사용한다.
    • 설정이 간단하지만, 여러 요청이 동시에 발생하면 성능저하가 발생할 수 있다.
  • createPool
    • 미리 설정한 개수만큼의 연결을 관리하는 풀을 생성한다. 클라이언트의 요청마다 사용가능한 연결을 할당하며, 작업 후에는 다시 반환하여 재사용한다.
    • 여러 쿼리를동시에 처리할 수 있고, 고부하 환경이나 웹 API등 동시 요청이 많은 환경에 적합하다.
    • 대신 풀의 크기와 설정에 따라 메모리 사용량이 증가할 수 있으며, 코드가 조금 복잡해질 수 있다.

수정된 코드

const order = async (req,res)=>{
    try{
        const {user_id, items, delivery, totalQuantity, totalPrice} = req.body;
        let deliveryId; let sql; let values;

        if (delivery.id){
            deliveryId = delivery.id;
        } else {
            // 배달 정보 넣기
            sql = `INSERT INTO delivery (address, receiver, contact) VALUES (?,?,?);`;
            values = [delivery.address, delivery.recevier, delivery.contact];
            const [deliveryResult] = await db.query(sql, values);
            deliveryId = deliveryResult.insertId;
        }
        
        // items를 가지고, 장바구니에서 book_id, quantity 조회
        sql = `SELECT book_id, quantity FROM cartItems WHERE id IN (?)`;
        let [orderItems] = await db.query(sql, [items]);

        // 주문서 
        sql = `INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id) VALUES ((SELECT title FROM books WHERE id = ?), ?, ?, ?, ?);`;
        values = [orderItems[0].book_id, totalQuantity, totalPrice, user_id, deliveryId];
        let [results] = await db.query(sql, values);
        let order_id = results.insertId;
        

        // orderedBook에 데이터 넣기
        sql = `INSERT INTO orderedBook (order_id, book_id, quantity) VALUES ?`;
        values = [];

        orderItems.forEach((item)=>{
            values.push([order_id, item.book_id, item.quantity]);
        })
        
        result = await db.query(sql,[values])
        await deleteCartItem(items);

        
        return res.status(StatusCodes.OK).json(result)
    }catch(err){
        console.log(err);
        return res.status(StatusCodes.BAD_REQUEST).end();
    }
}

const deleteCartItem = async(valueList) =>{
    const sql = `DELETE FROM cartItems WHERE id IN (?);`;
    const values = valueList;

    return await db.query(sql,[values])
}

클라이언트가 body의 item에 이전과 달리 cart_id만 준다고 가정했을때, 이를 가지고 장바구니를 불러오고, 그걸로 orderedBook, 장바구니 삭제 등을 구현하였다.
또한, for문을 사용하여 안에서 하나하나 삭제하던걸, 리스트로 받아와서 한번만 요청할 수 있도록 하였다.

이후 필요한 주문 내역 조회와 상세를 작성하였다.

  • 주문 내역 조회
const getOrders = async (req,res)=> {
    const {user_id} = req.body;
    let sql = `SELECT 
            o.id,
            o.book_title, 
            o.total_quantity, 
            o.total_price, 
            o.created_at,
            d.address, 
            d.receiver, 
            d.contact 
            FROM orders o 
            LEFT JOIN delivery d ON o.delivery_id = d.id 
            WHERE o.user_id = ?;`;
    let values = [user_id];
    let [rows, fields] = await db.query(sql, values);
    return res.status(StatusCodes.OK).json(rows);  
}
  • 주문 상세 조회
const getOrderDetail = async (req,res)=>{
    const order_id= req.params.id;
    let sql = `SELECT
            book_id,
            title,
            img, 
            author, 
            price, 
            quantity
        FROM orderedBook
        LEFT JOIN books ON orderedBook.book_id = books.id
        WHERE order_id = ?;`;
    let values = [order_id];
    let [rows, fields] = await db.query(sql, values)
    return res.status(StatusCodes.OK).json(rows);  
}
profile
일단 해!!!!

0개의 댓글