✅ Sequelize
ORM으로 분류되는 라이브러리
즉 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구이다
📝ORM(Object- relational Mapping)
객체 관계 매핑
데이터베이스와 객체지향 프로그래밍 언어 사이에
호환되지 않는 데이터를 변환하는 프로그래밍 기법
객체지향 언어에서 사용할 수 있는 가상 객체 DB를 구축하는 방법이다
✅ Sequelize 의존성 추가 및 초기 세팅
npm i sequelize sequelize-cli mysql2
npx sequelize init
🔨 config/config.json
{
"development": {
"username": "root",
"password": null,
"database": "database_development",
"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"
}
}
.env 의 process.env.NODE_ENV 의 값에 따라 db를 지정할 수 있다 (development, test, production)
username 와 password 를 각각 MySQL 계정에 맞게 수정해준다
database 는 nodejs 로 바꿔준다
"development": {
"username": "root",
"password": MYPASSWORD,
"database": "nodejs",
"host": "127.0.0.1",
"dialect": "mysql"
},
✅ models 폴더에 모델 추가
🔨 models/user.js
const Sequelize = require('sequelize');
module.exports = class User extends Sequelize.Model{
static init(sequelize){
return super.init({
email: {
type: Sequelize.STRING(40),
allowNull: false,
unique: true,
},
...
provider: {
type: Sequelize.STRING(10),
allowNull: false,
defaultValue: 'local',
},
}, {
sequelize,
timestamps: true,
underscored: false,
modelName: 'User',
tableName: 'users',
paranoid: true,
charset: 'utf8',
collate: 'utf8_general_ci',
});
}
static associate(db){}
};
super.init 메소드에서는 테이블 설정을
associations 메소드에서는 다른 모델과의 관계를 적는다
super.init 메소드의 첫번째 인수는 테이블 칼럼에 대한 설정이고
두번째 인수는 테이블 자체에 대한 설정이다
MySQL 의 자료형은 Sequelize 의 자료형으로 다음과 같이 바뀐다
MySQL | Sequelize |
VARCHAR(100) | STRING(100) |
INT | INTEGER |
TINYINT | BOOLEAN |
DATETIME | DATE |
INT UNSIGNED | INTEGER.UNSIGNED |
NOT NULL | allowNull: false |
UNIQUE | unique: true |
DEFAULT now() | defaultValue: Sequelize.NOW |
테이블 자체 옵션은 아래와 같다
sequelize | db.sequelize 객체를 넣어야함 |
timestamps | true - createAt, updatedAt 컬럼을 추가하며 자동으로 시간 입력 false - 추가하지 않음 |
underscored | true - 스네이크 케이스를 사용 false - 카멜 케이스를 사용 (기본값) |
modelName | 모델 이름 설정 |
tableName | 테이블 이름 설정 관행적으로 모델 이름을 소문자 + 복수형으로 만듬 (모델 User -> 테이블 users) |
paranoid | true - deletedAt 칼럼을 추가 로우를 조회할 때 deletedAt: null 인 값만 조회함 나중에 복원해야 할 필요가 있을 때 사용 false - 추가하지 않음 |
charset / collate | utf8 / utf8_general_ci 를 사용해야 한글을 입력할 수 있다 이모티콘까지 입력하고 싶다면 utf8mb4 / uft8mb4_general_ci 사용 |
🔨 models/index.js
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const User = require('./user');
const db = {};
const sequelize = new Sequelize(
config.database, config.username, config.password, config,
);
db.sequelize = sequelize;
db.User = User;
User.init(sequelize);
//User.associate(db);
module.exports = db;
원래 코드를 지우고 다음과 같이 바꾸어 User 모델과 데이터베이스를 연결했다
✅ 관계 정의하기(JOIN)
📝 1:N 관계 - hasMany, belongsTo
예를 들어 사용자의 정보에 대한 users 테이블과
게시글 정보에 대한 posts 테이블이 있을 때
사용자는 게시글을 여러개 적을 수 있지만
게시글을 작성한 사용자가 여러 명일 수는 없다 (일반적으로)
즉, User : Post = 1 : N
🔨 models/user.js
static associate(db){
db.User.hasMany(db.Post, { foreignKey: 'writer', sourceKey: 'id'});
}
// 또는
static associate(db){
db.User.hasMany(db.Post);
}
🔨 models/post.js
static associate(db){
db.Post.belongsTo(db.User);
}
// 또는
static associate(db){
db.Post.belongsTo(db.User, { foreignKey: 'writer', targetKey: 'id'});
}
foreignKey 를 지정하지 않는다면
user(모델명) + 기본키(id) 가 합쳐진 UserId 가 foreignKey 로 생성된다
📝 1:1 관계 - hasOne, belongsTo
만약 사용자 정보를 담는 Info 모델이 있다고 가정하면
아래와 같이 적을 수 있다
즉, User : Info = 1 : 1
db.User.hasOne(db.Info, { foreignKey: 'UserId', sourceKey: 'id'});
db.Info.belongsTo(db.User, { foreignKey: 'UserId', targetKey: 'id'});
📝 N:M 관계 - hasOne, belongsTo
Post 모델과 Hashtag 모델이 있다고 하면
아래와 같이 표현 가능하다
Post <-> PostHashtag <-> Hashtag
db.Post.belongsToMany(db.Hashtag, { through : 'PostHashtag' });
db.Hashtag.belongsToMany(db.Post, { through : 'PostHashtag' });
Post | PostHashtag | Hashtag | |||
id | content | postId | hashtagId | id | title |
1 | #cpp #python | 1 | 1 | 1 | cpp |
2 | #gengminy | 1 | 2 | 2 | pytyon |
3 | #javascript | 2 | 1 | 3 | javascript |
3 | 3 |
N:M 관계에서는 데이터를 조회할 때 여러 단계를 거쳐야 한다
자동으로 만들어진 모델(PostHashtag)도 다음과 같이 접근 가능하다
db.sequelize.models.PostHashtag
✅ 생성한 모델을 데이터베이스 및 서버와 연결하기
💻 console
npx sequelize db:create
// Sequelize CLI [Node: 16.10.0, CLI: 6.4.1, ORM: 6.19.2]
// Loaded configuration file "config\config.json".
// Using environment "development".
// Database database_development created.
🔨 app.js
const { sequelize } = require('./models');
...
sequelize.sync({ force: false })
.then(() => {
console.log('database connected!');
})
.catch((err) => {
console.error(err);
})
반드시 config/config.json 에서 데이터베이스 비밀번호를 설정해주도록 한다
IF NOT EXISTS 가 포함된 테이블 생성 쿼리문을 날려
테이블이 없어도 자동으로 테이블을 생성해준다
'📡 백엔드 > ⭐ Node.js' 카테고리의 다른 글
[Nodejs] passport 모듈로 로컬 로그인 전략 구현하기 (0) | 2022.05.24 |
---|---|
[Nodejs] Sequelize 로 SQL 쿼리 사용하기 (0) | 2022.05.21 |
[Nodejs] Router 객체로 라우팅 파일 분리 (0) | 2022.05.17 |
[Nodejs] 미들웨어의 사용과 자주 쓰이는 미들웨어 (0) | 2022.05.16 |
[Nodejs] express 서버 열기 (0) | 2022.05.15 |