📚요약
지난 시간은 비동기에 대해 배웠습니다. 이번 시간에는 이를 활용해 주문 API를 구현해 보겠습니다.
📖SQL
📄데이터 삭제
- DELETE : 조건(WHERE)을 사용할 경우 조건에 해당되는 데이터 삭제. 조건이 없는 경우 데이터 전부 삭제.
- DROP : 테이블 삭제.
- TRUNCATE : DELETE의 조건이 없는 경우와 동일하게 데이터를 전부 삭제한다. 하지만 추가적으로 auto_increment 옵션까지 초기화시켜 준다.
DELETE FROM table;
DROP TABLE table;
TRUNCATE table;
DELETE와 TRUNCATE의 큰 차이점은 Rollback의 가능 여부와 인덱스까지 삭제하는가의 차이입니다. 또한 일부 데이터를 삭제할 때는 무조건 DELETE만 가능합니다.
🍯tip! 데이터를 삭제하려고 하는 데 FK 때문에 삭제가 안 되는 에러가 발생할 수 있다. 그때는 이 글을 참고하면 좋을 것 같다.
[MySQL Error 1701] 외래키 설정이 되어 있는 테이블 데이터가 삭제가 안 되네?
에러 배경orders의 데이터를 TRUNCATE sql을 사용해 데이터를 삭제하려는 상황에서 발생했다.에러 그 잡채 TRUNCATE ordersError Code: 1701.Cannot truncate a table referenced in a foreign key constraint(`BookShop`.`orderedBook`,
nulzi-dev.tistory.com
📖주문 API
📄구현



📑주문하기
주문하기는 지금까지 요청들과 다르게 여러 SQL을 처리해야 했기 때문에 비동기적으로 처리하거나 다중 쿼리를 사용하는 방법을 이용해야 합니다. 이번에는 Promise와 async/await를 사용해서 비동기적으로 구현했습니다.
1. 테이블에 insert 하는 순서
delivery → orders → orderedBook
왜냐하면 orders에는 delivery의 id가 필요하고, orderedBook에는 orders의 id가 필요하기 때문입니다.
deliveryInsertSql = `INSERT INTO delivery (address, receiver, ph_num) VALUES (?,?,?)`
orderInsertSql = `INSERT INTO orders
(delivery_id, book_title, total_price, total_quantity, user_id)
VALUES (?,?,?,?,?)`
orderedBookInsertSql = `INSERT INTO orderedBook (order_id, book_id, quantity) VALUES ?`
2. 주문에 성공한 장바구니 목록 삭제하기
basketDeleteSql = `DELETE FROM baskets WHERE id IN (?)`
비동기를 활용해서 구현했기 때문에 이전과 조금 다르게 예외처리를 진행했습니다.
const order = async (req, res) => {
const catchError = (error) => {
res.status(StatusCodes.BAD_REQUEST).end();
throw error;
};
...
await addOrder(conn, values).catch(catchError);
// 이렇게 에러를 처리하면 서버가 정지하지 않고 400을 응답해준다.
...
}
구현 코드의 일부
const order = async (req, res) => {
const catchError = (error) => {
res.status(StatusCodes.BAD_REQUEST).end();
throw error;
};
const {
basketItemIds,
delivery,
totalQuantity,
totalPrice,
firstBookTitle,
userId,
} = req.body;
const mariadbP = require("mysql2/promise");
const conn = await mariadbP.createConnection({
host: "localhost",
port: process.env.DBPORT,
user: process.env.USER,
password: process.env.PW,
database: process.env.DATABASE,
dateStrings: true,
});
let values = [delivery.address, delivery.receiver, delivery.ph_num];
let results = await addDelivery(conn, values).catch(catchError);
let deliveryId = results.insertId;
values = [deliveryId, firstBookTitle, totalPrice, totalQuantity, userId];
results = await addOrder(conn, values).catch(catchError);
let orderId = results.insertId;
sql = `SELECT book_id, quantity FROM baskets WHERE id IN (?)`;
let [basketItems] = await conn.query(sql, [basketItemIds]).catch(catchError);
values = [];
basketItems.forEach((item) => {
values.push([orderId, item.book_id, item.quantity]);
});
results = await addOrderedBook(conn, values).catch(catchError);
results = await deleteSelectedBaskets(conn, basketItemIds)
.then((result) => {
if (!result.affectedRows)
return res.status(StatusCodes.BAD_REQUEST).end();
})
.catch(catchError);
res.status(StatusCodes.OK).json(results);
};
📑주문 목록 조회
sql = `SELECT orders.id, created_at, address, receiver, ph_num, book_title, total_quantity, total_price
FROM orders LEFT JOIN delivery
ON orders.delivery_id = delivery.id
WHERE user_id = ?`;
📑목록 상세 조회
sql = `SELECT book_id, title, img, price, author, quantity
FROM orderedBook LEFT JOIN books
ON book_id = books.id
WHERE order_id = ?`;
자세한 코드는 Github에서 확인할 수 있습니다.
ProgrammersSchool/PROJECT-BOOKSHOP at main · nulzi/ProgrammersSchool
프로그래머스 데브코스에서 학습하는 것들을 모아두는 레포. Contribute to nulzi/ProgrammersSchool development by creating an account on GitHub.
github.com
❔▪❓
Q. 주문하기를 구현할 때 중간에 API를 수정했는데 어떤 방식이 더 옳고 좋은지 모르겠다.
- FE에서 장바구니 목록에 담긴 정보(장바구니 id, 책 id, 수량)를 넘겨주기
- FE에서 장바구니 목록을 장바구니 id로만 넘겨주어 BE에서 SELECT로 처리하기
A. 개인적인 생각으로는 SQL의 요청이 많아지면 많아질수록 부담이 될 수 있기 때문에 간단한 SQL문이라도 사용을 덜 하는 편이 좋지 않을까 하는 생각이다.
Q. 주문 API - 주문하기에서 중간에 에러가 나서 delivery에만 입력된 경우나 orders에만 입력된 경우에는 어떻게 취소 처리 하고 다시 진행할 것인가?
A. SQL의 rollback 기능 활용??
다음 시간에 계속...
출처 & 참고
김송아 강사님의 강의
delete, truncate, drop 비교, 갓대희, 2024.05.31
'개발 > 프로그래머스 데브코스' 카테고리의 다른 글
| 프로그래머스 데브코스 41일차 with. TS 웹 풀스택 (0) | 2024.06.03 |
|---|---|
| 데브코스 스터디(알고리즘, 코테) 12회차 (1) | 2024.06.03 |
| 데브코스 스터디(알고리즘, 코테) 11회차 (0) | 2024.05.30 |
| 프로그래머스 데브코스 39일차 with. TS 웹 풀스택 (0) | 2024.05.30 |
| 프로그래머스 데브코스 38일차 with. TS 웹 풀스택 (0) | 2024.05.29 |