TIL1208 [MVC 패턴] ORM Sequelize 사용
Sequelize와 Sequelize-cli 를 모두 사용했습니다
MVC (Model, View, Controller) 역할
Model - 뷰에 표현되는 데이터
View - 모델에서 데이터를 받아 사용자에게 보이는 페이지
Controller - 사용자와 상호작용하며 사용자의 명령을 받아 Model을 변경시키고 변경된 사항을 View에 전달
ORM (Object Relation Mapping)을 사용하는 이유
ORM을 사용하면 객체(데이터)를 DB에 넣을 때 SQL문을 직접 사용하지 않아도 된다.
개발자가 ORM을 통해 명령을 전달하면 ORM은 명령에 맞는 SQL문을 DB에 전달해서 DB에 변경사항을 만든다.
ORM은 일종의 SQL 번역기라고 생각할 수 있다.
모델 작성
npx sequelize-cli init
먼저 init 을 실행해서 config, models, migrations, seeders 폴더를 생성한다.
config - 사용할 DB의 유저네임, 패스워드, db이름, 호스트 등의 환경설정을 할 수 있다. 환경을 변경하며 사용할 때 여기서 각각의 설정을 한다
models - DB에서 사용할 모델의 형식을 정의한다
migrations - DB 스키마 변경 이력이 저장된다. 스키마 형식도 저장되며, up과 down으로 migration과 migration:undo 명령시 어떤 작업을 할지 정의할 수 있다.
seeders - migration으로 테이블을 생성했을 때 테스트를 위해 임의로 넣어주는 DB 로우의 정보를 담는다.
npx sequelize-cli model:generate --name User --attributes firstName:string,lastName:string,email:string
새로운 모델 작성의 예시
--name '테이블명' --attributes '칼럼명:타입','칼럼명:타입
attributes 뒤에 칼럼명과 타입 여러개 적을 땐 콤마(,)뒤에 뛰어쓰기를 하면 에러가 발생하므로 띄우지말자.
attributes 의 데이터타입은 특정 DB를 따르는 것이 아닌 Sequelize ORM의 방식을 따르므로 공식문서대로 통일시켜 적는다.
npx sequelize-cli db:migrate
모델을 모두 작성했으면 migrate 명령어로 모델을 바탕으로 DB에 실제로 테이블을 생성한다.
npx sequelize-cli db:migrate:undo
스키마 작성이 잘못 되어서 테이블을 수정, 삭제해야 할 때는 migrate:undo 명령어로 migrate를 취소하고 테이블을 삭제(drop)할 수 있다.
마이그레이션은 스키마의 수정이 이루어질 때 마다 이력을 저장하므로 스키마 수정이력 관리를 할 수 있고, 모델만 작성하면 DB에 테이블을 작성할 수 있으므로 편리하다
Association
Sequelize는 Association이라는 개념으로 1:1 1:N N:N 의 테이블사이 관계를 표현할 수 있다.
mirations 폴더에 제약조건을 추가하고, models 폴더에서 Association 설정을 해준다.
Association 설정을 하면 findOne()으로 로우를 찾을(select) 때 include 옵션을 통해 관계가 형성된 로우까지 한번에 조회할 수 있다.(자동조인)
migrations 폴더에서
up 에 addConstraint()를 사용해서 칼럼에 foreign key 제약조건을 추가해주고,
down 에 removeConstraint() 를 사용해서 제약조건 생성시의 역순으로 제약조건이 제거될 수 있도록 작성한다.
models 폴더에선
const A = sequelize.define('A', /* ... */);
const B = sequelize.define('B', /* ... */);
A.hasOne(B); // A HasOne B
A.belongsTo(B); // A BelongsTo B
A.hasMany(B); // A HasMany B
A.belongsToMany(B, { through: 'C' }); // A BelongsToMany B through the junction table C
위처럼 공식문서를 참고하여 어느 모델의 어떤 칼럼이 어떤 관계를 갖는지 작성해준다.
A.hasOne(B) - 1:1 관계이며, B 모델에 foreign key 조건이 정의되어 있다.
A.belongsTo(B) - 1:1 관계이며, A 모델에 foreign key 조건이 정의되어 있다.
A.hasMany(B) - 1:N 관계이며, B 모델에 foreign key 조건이 정의되어 있다.
A.belongsToMany(B, { through: 'C' }) - N:N 관계이며, C 테이블을 조인테이블로 사용하고 C 테이블에 foreign key 조건이 정의되어 있다.