주문 DB
ERD
delivery 테이블 생성
orders 테이블 생성
orderedBook 테이블 생성
주문하기 API 구현
orders 테이블의 delivery_id 컬럼이 delivery 테이블을 참고하고 있고, orderedBook 테이블의 order_id 컬럼이 orders 테이블을 참조하고 있으므로 데이터 삽입 순서는 아래와 같다.
- delivery 테이블
- orders 테이블
- orderedBook 테이블
설계 수정
Method | POST |
URI | /orders |
HTTP Status Code | 성공(201) |
Request Body | { items: [ { cartId: 장바구니 도서 id, bookId: 도서 id, quantity: 수량 }, … ], delivery: { address: “주소”, receiver: “이름”, contact: “010-0000-0000” }, totalPrice: 총 금액, totalQuantity: 총 수량, userId: 사용자 id, firstBookTitle: “대표 도서 제목” } |
Response Body |
delivery 테이블 insert
results를 출력하면 위와 같은 객체를 볼 수 있다. 'insertId' 항목이 삽입된 데이터의 id를 알려주기 때문에 이 값을 저장해 놓으면 별도의 쿼리문을 실행하지 않아도 된다. 이 insertId는 orders 테이블에 데이터를 삽입할 때 필요하다.
const order = (req, res) => {
const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } = req.body;
let deliveryId;
let sql = `INSERT INTO delivery (address, receiver, contact)
VALUES (?, ?, ?)`;
let values = [delivery.address, delivery.receiver, delivery.contact];
conn.query(sql, values,
(err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
deliveryId = results.insertId;
});
};
orders 테이블 insert
쿼리 실행 결과의 insertId는 orderedBook 테이블에 데이터를 삽입할 때 필요하므로 별도로 저장해놔여 한다.
const order = (req, res) => {
const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } = req.body;
let deliveryId;
let orderId;
// ...
sql = `INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id)
VALUES (?, ?, ?, ?, ?)`
values = [firstBookTitle, totalQuantity, totalPrice, userId, deliveryId];
conn.query(sql, values,
(err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
orderId = results.insertId;
});
};
orderedBook 테이블 insert
이중 배열을 사용하면 쿼리를 여러 번 실행하지 않아도 복수개의 데이터를 한번에 삽입할 수 있다. 쿼리에 넣을 변수인 2차원 배열을 파라미터로 적어줄 때 대괄호를 입혀서 넣어야 한다.
const order = (req, res) => {
const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } = req.body;
let deliveryId;
let orderId;
// ...
sql = `INSERT INTO orderedBook (order_id, book_id, quantity) VALUES ?`;
values = [];
items.forEach((item) => {
values.push([orderId, item.bookId, item.quantity]);
});
conn.query(sql, [values],
(err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
res.status(StatusCodes.CREATED).json(results);
})
};
고쳐야 할 것
console.log(deliveryId)가 insertId를 저장하는 것보다 더 빨리 실행되기 때문에 콘솔에 나타나는 결과가 undefined이다.
const order = (req, res) => {
const { items, delivery, totalQuantity, totalPrice, userId, firstBookTitle } = req.body;
let deliveryId;
// ...
conn.query(sql, values,
(err, results) => {
// ...
deliveryId = results.insertId;
});
console.log(deliveryId) // undefined
};
배운 점
- 방금 INSERT 한 데이터의 id 값을 가져오는 방법에는 두 가지 방법이 있다.
- 쿼리 실행 결과 객체의 insertId 값 가져오기
- LAST_INSERT_ID() 함수를 사용하거나 MAX(id)를 조회한다. LAST_INSERT_ID() 함수는 시간차 때문에 오류가 발생할 수 있으므로 사용을 지양한다.
- 이중 배열을 사용하면 복수개의 데이터를 한 번에 삽입할 수 있다.
- 코딩 컨벤션이란 코딩 스타일 규칙을 말한다. 구성원들이 읽고 관리하기 쉽게 해 준다.
'데브코스' 카테고리의 다른 글
[8주차 복습 발표] 비동기 처리 (1) | 2024.04.18 |
---|---|
[8주차 - DAY4] 비동기 (0) | 2024.04.18 |
[8주차 - DAY2] 장바구니 API 구현 (0) | 2024.04.16 |
[8주차 - DAY1] 도서 API 구현(3) (0) | 2024.04.15 |
[7주차 - DAY5] 도서 API 구현(2) (0) | 2024.04.12 |