Sequelize#
Sequelize는 Node.js를 위한 현대적이고 강력한 Promise 기반 ORM(Object-Relational Mapping) 라이브러리.
관계형 데이터베이스와 상호작용하는 복잡한 작업을 단순화하고 추상화해준다.
ORM은 객체지향 프로그래밍 언어와 관계형 데이터베이스 사이의 번역기 역할을 한다.
복잡한 SQL 쿼리를 직접 작성하지 않고도 데이터베이스를 쉽게 조작할 수 있게 해준다.
Sequelize의 장점#
- 데이터베이스 추상화
- 강력한 관계 설정
- 데이터 검증
- 마이그레이션 지원
- 다양한 데이터베이스 호환성
주의사항#
- 대규모 애플리케이션에서는 성능 최적화 필요
- ORM의 복잡성을 이해해야 함
- 직접 SQL 쿼리도 학습 권장
Sequelize의 주요 특징#
- 다양한 데이터베이스 지원: MySQL, PostgreSQL, SQLite, MariaDB, MSSQL 등 여러 관계형 데이터베이스를 지원한다.
- 객체 지향적 접근: JavaScript 객체를 통해 데이터베이스 테이블을 표현하고 조작할 수 있다.
- 스키마 정의: 모델을 통해 데이터베이스 스키마를 정의하고 관리할 수 있다.
- 관계 설정: 모델 간의 관계(1:1, 1:N, N:M)를 쉽게 정의하고 관리할 수 있다.
- 쿼리 빌딩: SQL 쿼리를 직접 작성하지 않고도 JavaScript 메서드를 통해 데이터베이스 작업을 수행할 수 있다.
기본 설정 및 연결#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| const { Sequelize, DataTypes } = require('sequelize');
// 데이터베이스 연결
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql', // 사용하는 데이터베이스 종류
logging: false // SQL 로그 비활성화
});
// 연결 테스트
try {
await sequelize.authenticate();
console.log('데이터베이스 연결 성공!');
} catch (error) {
console.error('연결 실패:', error);
}
|
모델 정의와 관계#
기본 모델 생성#
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
| const User = sequelize.define('User', {
// 속성 정의
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING
},
email: {
type: DataTypes.STRING,
unique: true,
validate: {
isEmail: true
}
},
age: {
type: DataTypes.INTEGER,
validate: {
min: 18,
max: 100
}
}
}, {
// 모델 옵션
timestamps: true, // createdAt, updatedAt 자동 생성
});
|
모델 간 관계 설정#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // 1:N 관계 (One-to-Many)
const Post = sequelize.define('Post', {
title: DataTypes.STRING,
content: DataTypes.TEXT
});
// 사용자와 포스트 관계 정의
User.hasMany(Post);
Post.belongsTo(User);
// N:M 관계 (Many-to-Many)
const Project = sequelize.define('Project', {
name: DataTypes.STRING
});
User.belongsToMany(Project, { through: 'UserProjects' });
Project.belongsToMany(User, { through: 'UserProjects' });
|
CRUD 작업#
데이터 생성#
1
2
3
4
5
6
7
8
9
10
11
12
| // 단일 레코드 생성
const newUser = await User.create({
firstName: 'John',
lastName: 'Doe',
email: 'john@example.com'
});
// 대량 생성
await User.bulkCreate([
{ firstName: 'Alice', lastName: 'Smith' },
{ firstName: 'Bob', lastName: 'Johnson' }
]);
|
데이터 조회#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| // 모든 사용자 조회
const users = await User.findAll();
// 조건부 조회
const youngUsers = await User.findAll({
where: {
age: {
[Op.lt]: 30 // 30세 미만
}
},
include: [Post] // 연관된 포스트 함께 조회
});
// 단일 사용자 조회
const user = await User.findByPk(1);
|
데이터 업데이트#
1
2
3
4
5
| // 단일 레코드 업데이트
await User.update(
{ lastName: 'NewLastName' },
{ where: { id: 1 } }
);
|
데이터 삭제#
1
2
3
4
| // 단일 레코드 삭제
await User.destroy({
where: { id: 1 }
});
|
트랜잭션 처리#
1
2
3
4
5
6
7
8
9
10
11
12
13
| const result = await sequelize.transaction(async (t) => {
const user = await User.create({
firstName: 'Transactional',
lastName: 'User'
}, { transaction: t });
await user.createPost({
title: '첫 번째 포스트',
content: '트랜잭션 내 생성'
}, { transaction: t });
return user;
});
|
마이그레이션#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| // 마이그레이션 예시
module.exports = {
up: async (queryInterface, Sequelize) => {
await queryInterface.createTable('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
firstName: {
type: Sequelize.STRING
}
});
},
down: async (queryInterface, Sequelize) => {
await queryInterface.dropTable('Users');
}
};
|
학습 로드맵#
- JavaScript 기본 문법 숙달
- Node.js 기초 학습
- SQL 기본 개념 이해
- Sequelize 기본 CRUD 작업 연습
- 관계 모델링 및 고급 쿼리 학습
참고 및 출처#
Sequelize | Feature-rich ORM for modern TypeScript & JavaScript