티스토리 뷰
Web/Node.js
[Sequelize] 기본개념 / MySQL Query 대신에 Sequelize로 구현한 후기 및 코드 공유
angelatto 2021. 5. 17. 19:35※ Sequelize 개념 소개
▶ 우선, Sequelize란 Node.js ORM 프레임워크이다.
기본적으로 DB연결은 네트워크 통신을 필요로하고, 따라서 비동기 처리를 위해 Promise 기반으로 만들어져있다.
▶ Sequelize 하나로 다양한 DBMS (Postgres, MySQL, MariaDB, SQLite, Microsoft SQL Server)를 지원하지만,
각 SQL을 DBMS 특성마다 성능을 최적화시킬 수 없다는 아쉬움이 있다.
※ 프로젝트 적용 후기
▶ Sequelize를 사용하면 SQL문을 직접 작성하지 않아도 된다는 장점(?)이 있지만, SQL을 잘 아는 개발자라면 굳이 사용할 필요가 있나 싶었다. 그러나, 공부에 의의를 두고 NodeJS 기반의 프로젝트를 진행하면서 모든 SQL문을 적용해보았다.
▶ 프로젝트에 Sequelize 적용한 후기 :
생각보다 Sequelize Documentation이 다양한 SQL문을 다루지 않았고,
구글 선생님도 그다지 도움되지 않아서 혼자 고군분투해야 했다.
직접 SQL 쿼리를 다이렉트로 작성할 수도 있지만, 포기하지 않고 Sequelize로 모든 쿼리를 변환한것이 참 뿌듯했다.^^
※ MySQL <-> Sequelize 플젝 시 구현한 코드 공유
1. 주문 횟수가 가장 많은 TOP5 회원 구하기
getVipMembers: async function(){
try{
// Member와 OrderMain 조인
// 다(N).findAll
const result = await db.OrderMain.findAll({
attributes: [
'Member.member_name', 'order_memberid', 'Member.member_email',
[db.Sequelize.fn('count', db.Sequelize.col('order_memberid')), 'cnt']
],
include: [{
model: db.Member
}],
group: ['order_memberid'],
order: [[db.Sequelize.literal('cnt'), 'DESC']],
limit: 5
});
return result;
}catch(error){
throw error;
}
}
▶ 주의) include를 사용하려면 모델에 관계설정이 필요하다.
class OrderMain extends Model {
static associate(models) {
// 다 대 일(Member)
models.OrderMain.belongsTo(models.Member, {foreignKey:"order_memberid", targetKey:"member_id"});
}
}
2. 최근 한 달간 가입한 회원 수 구하기
getRecentJoinCount: async function(){
try{
// 한달 전 날짜 구하는 로직
const curr = new Date();
const lastDayofLastMonth = (new Date(curr.getYear(), curr.getMonth(), 0)).getDate();
if(curr.getDate() > lastDayofLastMonth) {
curr.setDate(lastDayofLastMonth);
}
curr.setMonth(curr.getMonth() - 1);
const result = await db.Member.count({
where: {
join_date: { [Op.gte]: curr}
}
});
return result;
}catch(error){
throw error;
}
}
3. 총 판매 금액 구하기
sumtotalprice: async function(){
try{
const result = await db.OrderMain.sum('order_price');
return result;
}catch(error){
throw error;
}
}
4. 최근 한 달 판매량 (해당 월) 구하기
totalpriceByMonth: async function(targetMonth){
try{
const result = await db.OrderMain.findOne({
attributes: [
[sequelize.fn('month', sequelize.col("order_date")), 'month'],
[sequelize.fn('sum', sequelize.col("order_price")), 'sum']
],
where: {
[Op.and]: [
sequelize.where(sequelize.fn('month', sequelize.col('order_date')), targetMonth)
]
}
});
return result.dataValues;
}catch(error){
throw error;
}
}
5. 최근 한 달 주문수 (해당 월) 구하기
salesCountByMonth: async function(targetMonth){
try{
const result = await db.OrderMain.findOne({
attributes: [
[sequelize.fn('month', sequelize.col("order_date")), 'month'],
[sequelize.fn('count', sequelize.col("order_id")), 'count']
],
where: {
[Op.and]: [
sequelize.where(sequelize.fn('month', sequelize.col('order_date')), targetMonth)
]
}
});
return result.dataValues;
}catch(error){
throw error;
}
}
6. 조건에 따른 정렬 구현하기
- 주의) order 속성을 const가 아닌 let으로 선언하기
list: async function(pager, orderType){
try{
let order = [["sabang_buycount", "DESC"]];
if(orderType){
if(orderType == 'view'){
order = [["sabang_viewcount", "DESC"]];
}else if(orderType == 'high'){
order = [["sabang_saleprice", "DESC"]];
}else if(orderType == 'low'){
order = [["sabang_saleprice", "ASC"]];
}
}
const result = await db.Sabang.findAll({
order,
limit: pager.rowsPerPage,
offset: pager.startRowIndex
});
return result;
}catch(error){
throw error;
}
}
7. 삭제할때 delete 아니고 destroy
deleteProduct: async function(product){
try{
// 1. 상품 테이블 삭제
await db.Product.destroy({where: {product_id: product.product_id}});
// 2. 사방 테이블 가격 갱신
await db.Sabang.decrement({
sabang_price: parseInt(product.product_price),
sabang_saleprice: parseInt(product.product_price)
}, {where:{sabang_id: product.sabang_id}});
}catch(error){
throw error;
}
}
8. 생성
createProduct: async function(product){
try{
// 1. 상품 테이블 등록
const dbBoard = await db.Product.create(product);
// 2. 사방 테이블 가격 갱신
await db.Sabang.increment({
sabang_price: parseInt(product.product_price),
sabang_saleprice: parseInt(product.product_price)
}, {where:{sabang_id: product.sabang_id}});
return dbBoard;
}catch(error){
throw error;
}
}
9. 주문 Id를 이용해 주문 정보와 회원 정보 동시에 가져오기
getOrderWithMemberInfo: async function(order_id){
try{
// 다 대 일 associate 관계 설정 이용
const order = await db.OrderMain.findOne({where: {order_id}});
order.dataValues.Member = await order.getMember();
return order;
}catch(error){
throw error;
}
}
▶ 주의) OrderMain 클래스에 "다대일" 관계 설정을 해야 getMember() 메소드(관계 설정 시 자동 생성)를 사용할 수 있다.
class OrderMain extends Model {
static associate(models) {
// 다 대 일(Member)
models.OrderMain.belongsTo(models.Member, {foreignKey:"order_memberid", targetKey:"member_id"});
}
}
'Web > Node.js' 카테고리의 다른 글
[Node.js] Node.js 개념 및 특징 (장단점 ★★★) (0) | 2021.05.19 |
---|---|
[Express] Express Framework 프로젝트 생성 및 구조 / Nunjucks 표현식 (0) | 2021.04.29 |
[NodeJS] 패키지 관리/ 외부 모듈(패키지) / npm (0) | 2021.04.29 |
공지사항
최근에 올라온 글
최근에 달린 댓글
- Total
- Today
- Yesterday
링크
TAG
- 백준
- 클래스와객체
- es6모듈
- 메이븐 저장소
- @functools.wraps
- 객체지향개념
- 자바스레드
- 백준2206 파이썬 풀이
- os
- @functools.lru_cache
- jre
- Git
- dynamic-project
- 생성자필드메소드
- ES6
- 자바스크립트Promise
- @functools.singledispatch
- sequelize.fn
- 정적멤버
- nunjucks
- 인스턴스멤버
- 자바스크립트Call-back
- yarn start
- 익명자식객체
- nodejs
- jdk
- java
- 사용자정의예외클래스
- method와 function
- 자바빌드도구
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 | 31 |
글 보관함