-
Sequelize - 시퀄라이즈 시작 (설정,모델만들기,관계설정)FrameWork/ORM 2024. 3. 21. 15:52
Sequelize(시퀄라이즈) 시작
MySQL 테이블 생성
- CREATE TABLE[데이터베이스명.테이블명]으로 테이블 생성
- 댓글 정보를 생성하는 테이블
create table comments( id int not null auto_increment, commenter int(11) not null, comment varchar(100) not null, created_at datetime not null default now(), primary key (id), INDEX commenter_idx (commenter ASC), CONSTRAINT commenter foreign key (commenter) references users(id) ON DELETE CASCADE ON UPDATE CASCADE) ENGINE = InnoDB DEFAULT CHARACTER SET = utf8 COMMENT = '댓글';
- INDEX : 테이블에서 자주 검색할 만한 칼럼에 지정한다. 검색 성능이 좋아진다. 위 테이블의 commenter의 인덱스 명은 commenter_idx로 원래 컬럼명과 겹치지 않게 정해주면 된다.
- CONSTRAINT : 다른 테이블과 관계가 있는 컬럼에 지정한다. 해당하는 칼럼에 특정 제약을 주는 옵션이다. 위 SQL에서는 commenter 칼럼에 foregin key(외래키)이면서 user 테이블의 id 칼럼을 references(참조)하고 있다는 제약을 설정하고 있다.
- ON DELETE CASCADE : users 테이블에서 id 1번을 가지는 사용자가 있다고 가정할 때 해당 사용자가 탈퇴를 해서 참조하고 있던 users 테이블의 id 1번에 대한 데이터가 삭제 되었을때 id 1번을 commenter로 참조하고 있는 comment 테이블의 정보도 지울 것이라는 의미를 가지고 있는 옵션이다.
- ON DELETE SET NUL : CASCADE와 같이 id 1번의 사용자 데이터가 사라질 때 comment의 정보를 삭제하지 않고 users 의 id를 참고하고 있는 commenter에 관련된 칼럼만 null로 변경 후 comment에 대한 데이터는 유지하겠다는 옵션이다.
- ON DELETE NO ACTION : 참조하고 있는 id 데이터가 삭제된 것에 대해 어떤 action도 하지 않는 옵션이다.
- CHARACTER SET = utf8mb4 :이모티콘도 사용가능 한 character set이다.
시퀄라이즈(Sequelize) ORM
DB작업을 쉽게 할 수 있도록 도와주는 라이브러리
- ORM (Object Relational Mapping) : 객체와 데이터를 매핑(1대 1 짝지음)
- MySQL 외에도 다른 RDB(Maria, Postgre, SQLite, MSSQL)과도 화환된다.
- 자바스크립트 문법으로 데이터베이스 조작 가능
시퀄라이즈 CLI 사용하기
- 앞으로 실습 환경에서 필요한 패키지들을 설치한다.
- mysql2는 MySQL DB가 아닌 드라이버이다.(Node.js와 MySQL을 이어주는 역할)
yarn add nunjucks sequelize sequelize-cli mysql
- npx sequelize init으로 시퀄라이즈 구조 생성
npx sequelize init
sequelize 명령어는 sequelize 모듈에 포함될 것이 아니라 CLI명령어로 시퀄라이즈를 다룰수 있도록 하는 sequelize-cli에 포하된 것이다. 위 명령어를 실행하면 config, models, migrations, seeders 폴더가 생겨난다. config 폴더에는 config.json 파일도 생성된다.
Sequelize 프로젝트와연결
models/index.js 수정
const Sequelize = require('sequelize'); const env = process.env,NODE_ENV || 'prod'; const config = require('../config/config')[env]; const db = {}; const sequelize = new Sequelize(config.database,config.username.config.password,config); //시퀄라이즈 인스턴스 db.sequelize = sequelize; module.export = db;
- models 폴더 안에 index.js가 생성되었는지 확인한다. sequelize-cli가 자동으로 생성해주는 코드는 그 대로 사용할 때 에러가 발생하고, 필요 없는 부분도 많기 때문에 위와 같이 수정한다.
- Sequelize는 시퀄라이즈 패키지이자 생성자이다. config/confi.json에서 데이터베이스 설정을 불러온 다음 new Sequelize를 통해 MySQL 연결 객체를 생성한다. 연결 객체를 나중에 재사용하기 위해 db.sequelize에 넣어둔다.
- Sequelize 객체는 하나 뿐이지만 sequelize는 Sequelize 생성자를 통해 하나 이상 생성할 수 있고 여러개의 시퀄라이즈 인스턴스를 생성하는것은 여러개의 DB에 연결하기 위함이다.
모델정의 하기
MySQL에서 정의한 테이블을 시퀄라이즈에서도 정의해야 한다. MySQL의 테이블은 시퀄라이즈의 모델과 대응된다. 시퀄라이즈는 모델과 MySQL의 테이블을 연결해주는 역할을 한다. User와 Commnet 모델을 만들어 users 테이블과 commnets테이블에 연결해보자. 시퀄라이즈는 기본적으로 모델이름을 단수형으로, 테이블 이름은 복수형으로 사용한다.
User 모델
user.js
const Sequelize = require('sequelize'); module.exports = class User extends Sequelize.Model{ static init(sequelize){ return super.init({ name:{ type: Sequelize.STRING(20), allowNull: false, }, email:{ type: Sequelize.STRING(225), allowNull:false, unique: true, }, password : { type: Sequelize.STRING(225), allowNull : false, }, age:{ type: Sequelize.INTEGER.UNSIGNED, allowNull: false, }, married:{ type: Sequelize.BOOLEAN, allowNull: isExcuteFalse, }, aboutMe : { type : Sequelize.TEXT, allowNull:true, }, created_at:{ defaultValue: Sequelize.NOW } },{ sequelize, timestamps:false, underscored:false, modelName:'User', tableName:'users', paranoid: false, charset:'utf8', collate:'utf8_general_ci' }); } static associate(db){} };
User 모델을 만들고 모듈로 exports했다. User 모델은 Sequelize.Model을 확장한 클래스로 선언한다. 클래스 문법을 사용하지만 클래스에 대한 지식 없어도 사용할 수 있다. 패턴만 숙지하면 된다. 모델은 크게 static init({},{}) 메서드와 static associate(){} 메서드로 나뉜다.
- static init() 메서드
- 테이블에대한 설정
- super.init() 메서드의 첫번 째 파라미터 : 테이블 컬럼에 대한 설정
- super.init() 메서드의 두번 째 파라미터 : 테이블 자체에 대한 설정
- static associate() 메서드
- 다른 모델과의 관계를 적는다.
시퀄라이즈는 알아서 id를 기본 키로 연결하므로 id 컬럼은 적어줄 필요가 없다. 나머지 컬럼의 스펙을 입력한다. MySQL 테이블과 컬럼 내용이 일치해야 정확하게 대응된다.
시퀄라이즈 자료형
- VARCHAR(100) → STRING(100)
- INT → INTEGER
- INTEGER.UNSIGED → UNSIGED 옵션이 적용된 INT를 의미한다.
- 여기에 ZEROFILL 옵션도 사용하고 싶다면 INTEGER.UNSIGNED.ZEROFILL을 적는다.
- TINYINT → BOOLEAN
- DATETIME → DATE
- DATE → Dateonly
시퀄라이즈 옵션
- allowNull : NOT NUL 옵션과 동일하다.
- unique : UNIQUE 옵션이다.
- defaultValue : 기본값 (DEFAULT)을 의미한다.
super.init 메서드의 두번째 인수
super.init 메서드의 두 번째 인수는 테이블 옵션이다.
- sequelize : static init 메서드의 매개변수와 연결되는 옵션으로 db.sequelize 객체를 넣어야 한다. 나중에 model/index.js에서 연결한다.
- timestamps : User모델을 정의한 위 코드에서는 false로 되어 있으면, 해당 속성 값이 true이면 시퀄라이즈는 createdAt과 updatedAt 컬럼을 추가한다. 각각 로우가 생성될 때와 수정될 때의시간이 자동으로 입력된다. 하지만 예제에서는 직접 created_at 컬럼을 만들었으므로 timestamps 속성이 필요하지 않다. 따라서 속성값을 false로 하여 자동으로 날짜 컬럼을 추가하는 기능을 해제한다.
- underscored : 시퀄라이즈는 기본적으로 테이블명과 컬럼명을 캐멀 케이스(camel case)(예시: createdAT)로 만든다. 이를 스네이크 케이스(snake case)(예시: create_at)로 바꾸는 옵션이다.
- modleName : 모델 이름을 설정할 수 있다. 노드 프로젝트에서 사용한다.
- tableName : 실제 데이터베이스의 테이블 이름이 됩니다. 기본적으로는 모델 이름을 소문자 및 복수형으로 만든다. 모델 이름이 Users라면 테이블 이름은 users가 된다.
- paranoid : true로 설정하면 deletedAt이라는 컬럼이 생긴다. 로우를 삭제할 때 완전히 지워지지 않고 deletedAt에 지운 시각이 기록된다.
- charset과 collate : 각각 utf8과 utf8_general_ci로 설정해야 한들이 입력된다. 이모티콘까지 입력할 수 있게 만들고 싶다면 utf8mb4와 utf8mb4_general_ci를 입력한다.
Comment
commnet.js
const Sequelize = require('sequelize'); const { associate } = require('./user'); module.exports = class Comment extends Sequelize.Model{ static init(sequelize){ return super.init({ comment:{ type: Sequelize.STRING(100), allowNull: false }, created_at:{ type:Sequelize.DATE, allowNull: true, defaultValue: Sequelize.NOW }, },{ sequelize, timestamps:false, modelName:'Commnet', tableName:'comments', paranoid: false, charset:'utf8mb4', collate:'utf8mb4_general_ci' }); } static associate(db) {} }
Comment 모델을 보면 users테이블과 연결된 commenter 컬럼이 없다. 이 부분은 모델을 정의할 때 넣어도 되지만, 시퀄라이즈 자체에서 관계를 따로 정의할 수 있다. 이는 조금뒤에 알아보자.
models/index.js
'use strict'; const process = require('process'); const Sequelize = require('sequelize'); const env = process.env.NODE_ENV || 'prod'; const config = require('../config/config')[env]; const db = {}; const sequelize = new Sequelize(config.database,config.username,config.password,config); //모델 import const User = require('./user.js'); const Comment = require('./comment.js'); //시퀄라이즈 인스턴스 db.sequelize = sequelize; db.User = User; db.Comment = Comment; User.associate(db); Comment.associate(db); module.exports = db;
db라는 객체에 User와 Comment 모델을 담아두었다. 앞으로는 db객체를 require하여 User와 Comment 모델에 접근할 수 있다. User.init과 Commnet.init은 각각 모델의 static.init 메서드를 호출하는것이다. init이 실행되어야 테이블이 모델과 연결된다. 다른 테이블과의 관계를 연결하는 associate 메서드도 미리 실행해둔다.
[출처 - [개정3판]Node.js 교과서 - 기본부터 프로젝트 실습까지, 저 조현영]
https://www.inflearn.com/course/%EB%85%B8%EB%93%9C-js-%EA%B5%90%EA%B3%BC%EC%84%9C
'FrameWork > ORM' 카테고리의 다른 글
Prisma - 객체 간의 관계 설정, 1:N, 1:1, N:M (0) 2024.04.16 Prisma - 🐠시작하기 환경설정, 쿼리 로깅, CRUD (0) 2024.04.12 ORM - 영속성 관리(플러시, 준영속) (1) 2024.02.29 ORM - 영속성 관리(엔티티 등록,수정,삭제) (0) 2024.02.29 ORM - 영속성관리(엔티티 매니저 팩토리와 엔티티 매니저) (1) 2024.02.28