February 14, 2021

시퀄라이즈(Sequelize)

MySQL 작업을 쉽게 할 수 있도록 도와주는 라이브러리이다.

ORM(Object-relational Mapping)으로 분류된다. 이는 자바스크립트 객체와 데이터베이스의 릴레이션을 매핑해주는 도구이다.

MySQL 연결하기

const Sequelize = require('sequelize');
const User = require('./user');
const Comment = require('./comment');

const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};

const sequelize = new Sequelize(config.database, config.username, config.password, config);

db.sequelize = sequelize;

db.User = User;
db.Comment = Comment;

// 각각의 모델의 init 메소드 실행
// 테이블이 모델로 연결
User.init(sequelize); 
Comment.init(sequelize);

// 다른 테이블과의 관계 연결
User.associate(db);
Comment.associate(db);

module.exports = db;
const express = require('express');
const path = require('path');
const morgan = require('morgan');
const nunjucks = require('nunjucks');

const { sequelize } = require('./models');

const app = express();

app.set('port', process.env.PORT || 3000);
app.set('view engine', 'html');

nunjucks.configure('views', {
	express: app,
	watch: true,
});

// 서버 실행 시 MySQL과 연동
sequelize.sync({ force: false })
	.then(() => {
		console.log('데이터베이스 연결 성공');
	})
	.catch((err) => {
		console.log(err);
	});

app.use(morgan('dev'));
app.use(express.static(path.join(__dirname, 'public')));
app.use(express.json());
app.use(express.urlencoded({ extended: false }));

app.use((req, res, next) => {
	const error = new Error(`${req.method} ${req.url} 라우터가 없습니다.`);
	error.status = 404;
	next(error);
});

app.use((err, req, res, next) => {
	res.locals.message = err.message;
	res.locals.error = process.env.NODE_ENV !== 'production' ? err : {};
	res.status(err.status || 500);
	res.render('error');
});

app.listen(app.get('port'), () => {
	console.log('대기중');
})

sync 메소드를 이용하여 서버 실행 시 MySQL과 연동된다. force: false 옵션의 경우 이 옵션을 true로 설정하면 서버 실행 시마다 테이블을 재생선한다.

MySQL과 연동할 때에는 config 폴더 안의 config.json 정보가 사용된다.

모델 정의하기

모델은 크게 static init 메소드와 static associate 메소드로 나뉜다.

init 메소드에서는 테이블에 대한 설정을 하고, associate 메소드에서는 다른 모델과의 관계를 적는다.

시퀄라이즈는 id를 기본 키로 연결하므로 id 컬럼은 적지 않아도 되며, 나머지 컬럼은 정확하게 일치해야한다.

const Sequelize = require('sequelize');

module.exports = class User extends Sequelize.Model {
	static init(sequelize) {
		return super.init({
			name: {
				type: Sequelize.STRING(20),
				allowNull: false,
				unique: true,
			},
			age: {
				type: Sequelize.INTEGER.UNSIGNED,
				allowNull: false,
			},
			married: {
				type: Sequelize.BOOLEAN,
				allowNull: false,
			},
			comment: {
				type: Sequelize.TEXT,
				allowNull: true,
			},
			created_at: {
				type: Sequelize.DATE,
				allowNull: false,
				defaultValue: Sequelize.NOW,
			},
		}, {
			sequelize,
			timestamps: false,
			underscored: false,
			modelName: 'User',
			tableName: 'users',
			paranoid: false,
			charset: 'utf8',
			collate: 'utf8_general_ci',
		});
	}
	
	static associate(db) {}
}

시퀄라이즈의 자료형은 MySQL의 자료형과 조금 다르다.

<aside> 💡 super.init 메소드의 두 번째 인수인 테이블 옵션은 필요할 때 돌아와서 다시 보자!

</aside>

관계 정의하기

1:N

사용자 한 명은 여러개의 댓글을 작성할 수 있지만, 각 댓글의 작성자는 한명이다.

...
    static associate(db) {
        db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id' });
    }
};