저번시간에는 visitor파일들이 많아서 visitor지옥이었는데요.. .오늘은 sequelize변수들이 많아서 sequelize지옥이었습니다..
sequelize지옥 같이한번 가볼까요?><ㅋㅋㅋㅋㅋㅋㅋㅋ
일단 먼저 sequelize가 뭔지, 왜 사용하는지부터 알아야겠죠?
우선 Sequelize는 자바스크립트 구문을 알아서 SQL로 변환해주는 것을 말하는데요
DB작업을 쉽게 할 수 있도록 도와주는 ORM라이브러리 중 하나입니다.
여기서 ORM이란 Object Relation Mapping의 약자로 객체의 데이터베이스 관계를 연결하는 도구 즉, 프로그래밍언어의 객체와 데이터베이스 사이의 중계역할을 하는 것입니다.
Sequelize가 어떻게 사용되는지는 앞선 프로젝트에서 MySQL패키지를 이요해서 model모듈이 DB에 접근했었는데요, 이 방식의 경우 sql문을 개발자가 직접 작성하고, 앞선 포스팅을 보시면 아시겠지만 callback함수를 이용해서 순서를 지정해야했었기 때문에 가독성이 떨어지는 문제가 있었습니다.
ORM을 이용하면 Promise기반으로 코드를 작성할 수 있기때문에 가독성이 향상되겠죠?
Sequelize를 이용한다는건 동작에 대해서는 변화가 없으나 서버측 코드는 바뀌는 것입니다.
그러니 앞선 프로젝트가 정말정말 중요했겠죠?
아무튼, Sequelize를 이용하면 다음과 같은 장점들이 있습니다.
1. sql문을 작성하지 않고, CRUD를 구현
2. sequelize 라이브러리는 promise 패턴 기반 비동기 제어 간편(코드 가독성 향상)
3. 특정 DBMS에 종속적이지 않다(즉, 여러 DBMS를 지원(그래서 MySQL에서 서비스를 완성하더라도 ORACLE에서 작동 가)
그럼 Sequeilze설치부터 해보죠?
먼저 npm install sequelize sequelize-cli mysql2를 해줍니다.
여기에서 sequelize는 시퀄라이즈 패키지
sequelize-cli:시퀄라이즈 명령어 실행
mysql2: mysql과 시퀄라이즈를 연결하는 드라이버(도구)
이렇게 설치를하면
package.json에 이렇게 설치가 되어있어야 합니다.
다음으로, npx sequelize init
sequelize init 명령어를 호출하면
이렇게 몇몇 새로운 폴더들이 새롭게 등장합니다.
이 중에서 config파일은 database정보를 정의합니다.
저는 config.json파일을
{
"development": {
"username": "user",
"password": "1234",
"database": "codingon",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
이렇게 정의해주었구요,
다음으로 이전 코드들이 sequelize를 사용하면 어떻게 바뀌는지 자세히 살펴보도록 하겠습니다.
시퀄라이즈는 promise기반이니까 async-await다들 기억 하시죠? 그래서
컨트롤러의 코드가
//옛날 코드..//const Visitor = require('../model/Visitor');
//const models = require('../models'); //../models/index.js
//db={sequelize,Sequelize, Visitor:모델(테이블)}이게 불러와짐
//구조분해로 꺼내오기..
const { Visitor } = require('../models');
exports.main = (req, res) => {
res.render('index');
};
//read all
exports.getVisitors = async (req, res) => {
// [before]
// res.render('visitor', { data: Visitor.getVisitors() });
// [after-> before]
// console.log(Visitor.getVisitors())
// Visitor.getVisitors((result) => {
// console.log('controller >>', result);
// res.render('visitor', { data: result });
// });
//[after]
//여기서 Visitor는 객체구조분해한거
const result = await Visitor.findAll();
console.log(result);
res.render('visitor', { data: result });
};
//create
exports.postVisitor = async (req, res) => {
//[before]
// console.log(req.body); // { name: xx, comment: yy }
// const { name, comment } = req.body;
// Visitor.postVisitor(req.body, (insertId) => {
// console.log('controller >> ', insertId);
// res.send({ id: insertId, name: name, comment: comment });
// });
//[after]
const { name, comment } = req.body;
const result = await Visitor.create({
name,
comment,
});
// console.log(result);//visitor라는 객체가 result로 찍히게 됨(==insert한 데이터 값==create메서드가 실행된 결과)
res.send('임시응답!');
};
//delete
exports.deleteVisitor = async (req, res) => {
//[before]
// console.log(req.body); // { id: xx }
// const { id } = req.body;
// Visitor.deleteVisitor(id, (result) => {
// console.log('controller >>', result); // true
// res.send(result); // res.send(true)
//});
//[after]
const { id } = req.body;
const result = await Visitor.destroy({
where: { id: id },
});
console.log(result); //result는 destroy한 결과
res.send(true); //삭제나 수정에서 응답방식이 true나 false 값을 던지기도 하고 , 바뀐 값을 던져주기도 하는데 여기에서 result를 넘겨주게되면 front js에서 처리할 값이 없기 떄문에 에러가 뜨게 된다.
//그래서 삭제 성공을 의미하는 true값을 보내면 된다.
};
//read one
exports.getVisitor = async (req, res) => {
//[before]
// // GET/visitor?id=5 --> 컨트롤러에서는 req.query(쿼리 스트링 썼을 떄)
// // GET/visitor/:id-->컨트롤러에서는 req.params(param썼을 떄)
// console.log(req.params); //{id:'5'}//id가 문자열 형태로 넘어오네...--> 숫자로 바꿔야할듯?database에서 id값 숫자형태임
// // console.log(req.query); //컨트롤러에서 param썼으니까~
// const { id } = req.params;
// Visitor.getVisitor(id, (result) => {
// console.log(result);
// //[ RowDataPacket { id: 6, name: 'ㅇㅁㅇㄹ', comment: 'ㅁㄴㅇㄹ' } ]배열안에 객체 하나가...
// //그런데 row[0]으로 넘겨줬으니까
// //result는 모델의 getVisitor callback의 인자 (rows[0])이다!!
// res.send(result);
// });
//[after]
const { id } = req.params;
const result = await Visitor.findOne({
where: { id: id },
});
console.log(result);
res.send(result);
};
//update
exports.updateVisitor = async (req, res) => {
//[before]
// console.log(req.body); //{id:x, name:x, comment:x}
// Visitor.updateVisitor(req.body, (result) => {
// console.log(result);
// res.send({ isUpdated: true });
// }); //수정되어야 할 데이터가 req.body에 들어있음
//[after]
//.update({변경될 값},{where절})
await Visitor.update(
{
name: req.body.name,
comment: req.body.comment,
},
{
where: { id: req.body.id },
}
);
res.send({ isUpdated: true });
};
이렇게 바뀐답니다!!
그리고 sequelize를 사용하면 javascript코드로 직접 sql문을 사용할 수 있으니 테이블을 추가하는것도 가능하겠죠? 그래서 models/Visitor에서 모델을 정의해서
//visitor 모델 정의
const Visitor = (Sequelize, DataTypes) => {
//Sequelize:models/index.js에서 sequelize
//DataTypes:models/index.js에서 Sequelize
const model = Sequelize.define(
'visitor',
{
//id int not null primary key auto_increment,
id: {
type: DataTypes.INTEGER,
allowNull: false,
primaryKey: true,
autoIncrement: true,
},
//name varchar(10) not null,
name: {
type: DataTypes.STRING(10),
allowNull: false,
},
comment: {
//comment MEDIUMTEXT
type: DataTypes.TEXT('medium'),
},
},
{
tableName: 'visitor', //실제 DB 테이블 명
freezeTableName: true, //테이블명 고정(모델 이름 테이블로 바꿀 떄 복수형으로 바뀜)
timestamps: true,
}
);
return model;
};
module.exports = Visitor;
이렇게 만들어서 내보낼 수 있습니다. 그러니까 MySQL에서 테이블이 Sequelize에서 모델이라고 볼 수 있겠죠?
'use strict'; //엄격모드--> 디버깅이 쉬워진다...
//sequelize 모듈 호출해서 Sequelize변수에 저장
const Sequelize = require('sequelize'); //sequelize 패키지를 불러와서 Sequelize변수에 저장함
//config.json 파일을 불러와서 development 환경의 db설정
//config:db접근 가능한 설정값저장
const config = require(__dirname + '/../config/config.json')['development']; //현재위치에서 한단계 올라가서 config폴더의 json파일을 읽어오고
//빈 db객체 생성
const db = {};
//Sequelize객체 생성해서 sequelize 변수에 저장
const sequelize = new Sequelize( //config에서 불러온 거
config.database, //sesac
config.username, //user
config.password, //1234
config //{}
);
//db={sequelize: sequelize, Sequelize:Sequelize}
db.sequelize = sequelize;
db.Sequelize = Sequelize;
//!! models/폴더에 정의되는 model(테이블)은 db객체에 저장해서 쓸 수 있도록 할거다.
//db={sequelize,Sequelize, Visitor:모델(테이블)}
db.Visitor = require('./Visitor')(sequelize, Sequelize);
//db객체 내보냄(모듈화 내보냄... 다른 곳에서 db객체 사용 가능)
module.exports = db; //db={sequelize,Sequelize, Visitor:모델(테이블)}
이건 models/index.js 파일인데요, 앞의 models/Visitor.js모델을 내보낼 때 필요한 데이터베이스를 정의해서 내보내는 그런 역할을 하는 거라 보면 되겠죠?
네.. 시퀄라이즈는 이게 끝입니다.. 생각보다 정리해보니 앞의 프로젝트만 이해하면 크게 어려운건 없었네요..
기억해야할것은 모델에서 행 전체를 읽어오려면 .findAll(), 일부만 선택해서 읽어오려면 .findOne(), 삭제하려면 .destory(), 수정하려면 .update({변경될 값},{where절}), 생성하려면 .create()해주면 됩니다!
생각보다 별거 없었던 시퀄라이즈..하지만 남은 쿠키...빨리 해볼게요
'[새싹X코딩온]웹 풀스택' 카테고리의 다른 글
[새싹X코딩온]웹 풀스택 8주차(9/4)회고록|세션, 암호화, 환경변수설정 (0) | 2023.09.07 |
---|---|
[새싹X코딩온]웹 풀스택 7주차(9/1)회고록|Rest API & DB응용 & cookie (1) | 2023.09.03 |
[새싹X코딩온]웹 풀스택 7주차(8/28)회고록|MVC에 MySQL연결하기 (1) | 2023.09.02 |
[새싹X코딩온]웹 풀스택 6주차(8/25)회고록|MYSQL+MVC패턴 (0) | 2023.08.30 |
[새싹X코딩온]웹 풀스택 6주차(8/23)회고록|데이터베이스, MYSQL, SQL문법 (0) | 2023.08.24 |