주문서 작성 > 주문 API
user_id 있어야 한다.
전체 ERD
테이블 생성 delivery, orders, orderedBook
fk 컨벤션 정하고 플젝 시작하기!
Ref: orders.delivery_id > delivery.id
Ref: orderedBook.order_id > orders.id
Ref: orderedBook.book_id > books.id
Ref: orders.user_id > users.id
주문 등록 INSERT, 주문된 상품은 DELETE
{
items : [{ //orderedBook INSERT
cartItemId : 장바구니 도서 id,
bookId : 도서 id,
quantity: 수량
}, {
cartItemId : 장바구니 도서 id,
bookId : 도서 id,
quantity: 수량
},…],
delivery : { //delivery INSERT
address : “주소”,
receiver : “이름”,
contact : “010-0000-0000”
}
totalQuantity : 총 수량, //orders INSERT
totalPrice : 총 금액,
userId : 회원 id
}
delivery > orders > ordered Book INSERT 순서
delivery 배송정보 INSERT
INSERT INTO delivery (address, receiver, contact) VALUES ("경기도", "닿", "010-1111-1111");
orders 주문정보 INSERT
대표 책제목? 가지고 있을지, JOIN을 걸지,,
// 주문 정보 입력
INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id)
VALUES ("어린왕자들", 3, 60000, 1, 1);
const order_id = SELECT max(id) FROM orders;
orderedBook 주문 상세 목록 입력 INSERT
// 주문 상세 목록 입력
INSERT INTO orderedBook (order_id, book_id, quantity)
VALUES (1, 1, 1);
INSERT INTO orderedBook (order_id, book_id, quantity)
VALUES (2, 3, 2);
MAX()
LAST_INSERT_ID() : 시간차 공격 : 이전 값을 들고오는 간간히 오류가 난다. `SELECT last_insert_id();`
`SELECT max(id) FROM 테이블`
제일 최신값 = 제일 마지막에 INSERT된 최근값 = id 가 제일 큰 값
order 구현 + 고도화
배송정보 등록
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();
}
return res.status(StatusCodes.OK).json(results);
});
bookId 보낼때 bookTitle 도서제목 함께 보내기
sql = `INSERT INTO orders (book_title, total_quantity, total_price, user_id, delivery_id)
VALUES (?, ?, ?, ?, ?)`;
values = [firstBookTitle, totalQuantity, totalPrice, userId, delivery_id];
conn.query(sql, values, (err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
order_id = results.insertId;
console.log(order_id);
return res.status(StatusCodes.OK).json(results);
});
그리고 INSERT를 벌크 `BULK` 로 처리한다 : 두번 연속으로 실행한다.
nodejs는 이중(이차원) 배열을 처리해준다!
sql = `INSERT INTO orderedBook (order_id, book_id, quantity) VALUES ?;`;
//items 배열 요소를 하나씩 꺼내서 forEach > 이차원 배열로 값 던지기
values = [];
items.forEach((item) => {
values.push([order_id, item.book_id, item.quantity]);
});
conn.query(sql, [values], (err, results) => {
if (err) {
console.log(err);
return res.status(StatusCodes.BAD_REQUEST).end();
}
return res.status(StatusCodes.OK).json(results);
});
☑️ 배운 점
BULK INSERT : 다량의 데이터를 한번에 DB에 집어넣으려 할때 사용한다. 이차원 배열 활용!
LAST_INSERT_ID()는 동시간대에 입력된 SQL문을 구분하지 못하고 에러가 발생하므로, 입력순으로 처리되는 id의 MAX 값을 찾는 것이 더 이상적이다.
이번에 외래키 적용해서 DB 생성할때 휴먼오류가 몇번 있어서 Auto Increment 자동 숫자 입력이 밀렸는데,,, 3,4,10,... 등으로 아이디가 부여되었다ㅜㅜ 그래서 fk를 테스트할때 복잡해서 시간이 배로 걸렸다.. 이거.. 다시 설정하는방법은 테이블 재생성이라고 하는데,, 이게 맞나ㅜㅜ 내일 해야겠다... 슬품