애플리케이션을 세 가지 역할로 구분하는 설계도 입니다.
이러한 패턴을 사용하는 이유는 물론 효율입니다. 세 가지 역할로 분리함으로 각자의 역할에 집중할 수 있고, 유지보수성과 애플리케이션의 확장, 유연성이 증가하게됩니다.
각자의 역할이 무엇인지 초점을 맞추면 왜이렇게 만들었으며, 앞으로 다른 설계를 볼 때도 참조할 수 있을 것입니다.
규칙
- 사용자가 편집하길 원하는 모든 데이터를 가지고 있어야한다.
- 뷰나 컨트롤러에 대해서 어떤 정보도 알지 말아야한다.
- 변경이 일어나면, 변경 통지에 대한 처리방법를 구현해야만 한다.
규칙
- 모델이 가지고 있는 정보를 따로 저장해서는 안된다.
- 모델이나 컨트롤러와 같이 다른 구성요소들을 몰라야 된다.
- 변경이 일어나면, 변경 통지에 대한 처리방법을 구현해야만 한다.
규칙
- 모델이나 뷰에 대해서 알고 있어야한다.
- 모델이나 뷰의 변경을 모니터링 해야한다.
프로미스 기반 Node.js환경에서 사용할 수 있는 ORM 입니다.
sequelize에 대해 먼저 공부해야될께 있는데 ORM 입니다. ORM 이란 'Object Relational Mapping의 약자로 객체(클래스)와 관계(관계형 데이터 베이스)의 설정을 의미합니다.
객체 지향 프로그래밍은 클래스를 , 관계형 데이터베이스는 테이블을 사용하기에 불일치 합니다. 이를 객체간의 관계를 바탕으로 SQL을 자동 생성하여 해결합니다.
npm install --save sequelize
npm install --save sequelize-cli
sequelize-cli는 sequelize-cli가 마이그레이션을 할 수있도록 돕는 툴로, cli에서 모델을 생성해주거나, 스키마 적용을 할 수 있도록 도와줍니다.
npx sequelize-cli init
실행하고 나면 config, models, migrations, seeders 폴더가 생깁니다.
models/index.js파일은 다음과 같은 과정을 수행합니다.
1. /config/config.json 파일의 설정값을 읽어 sequelize를 생성하고
2. models 폴더 아래에 존재하는 js파일을 모두 로딩한 후
3. db 객체에 Model을 정의하여 반환합니다.
npx sequelize-cli model:generate --name User --attribute firstName:string,lastName:string,email:string
정의하면 migrations과 models 폴더에 각 파일이 생성됩니다.
const Sequelize = require('sequelize');
class User extends Sequelize.Model {
// 스태틱 메소드
// 테이블에 대한 설정
static init(sequelize) {
return super.init(
{ // 첫번째 객체 인수는 테이블 필드에 대한 설정
name: {
type: Sequelize.STRING(20),
allowNull: false,
unique: true,
},
age: {
type: Sequelize.SMALLINT,
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, /* static init 메서드의 매개변수와 연결되는 옵션으로, db.sequelize 객체를 넣어야 한다. */
timestamps: false, /* true : 각각 레코드가 생성, 수정될 때의 시간이 자동으로 입력된다. */
underscored: false, /* 카멜 표기법을 스네이크 표기법으로 바꾸는 옵션 */
modelName: 'User', /* 모델 이름을 설정. */
tableName: 'users', /* 데이터베이스의 테이블 이름. */
paranoid: false, /* true : deletedAt이라는 컬럼이 생기고 지운 시각이 기록된다. */
charset: 'utf8', /* 인코딩 */
collate: 'utf8_general_ci'
}
);
}
// 다른 모델과의 관계
static associate(db) { // 인자로 index.js에서 만든 여러 테이블이 저장되어있는 db객체를 받을 것이다.
db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id', onDelete: 'cascade', onUpdate: 'cascade' });
// db.User (hasMany) db.Comment = 1:N 관계 이다.
// db.User는 가지고있다. 많이. db.Comment를
}
};
module.exports = User;
모델은 static init메서드와 static associate메서드로 나누어집니다.
init 메서드에서는 테이블에 대한 설정을 합니다.
super.int의 첫 번째 인수는 테이블에 대한 설정
두 번째 인수는 테이블 자체에 대한 설정입니다.
super.init의 두번쨰 인수는 테이블 옵션입니다.
sequelize: static init메서드의 매개변수와 연결되는 옵션으로 db.sequelize 객체를 넣어야합니다. 나중에 model/index.js에서 연결합니다.
timestamps: createdAt열과 updateAt열을 추가할지 여부입니다.
underscored: 시퀼라이즈는 기본적으로 테이블명과 컬럼명을 카멜 표기법으로 만듭니다. 이를 스네이크 표기법으로 바꾸는 옵션입니다. (ex updateAt => updated_at)
modelName: 모델이름을 설정할 수 있습니다.
tableName: 실제 데이터베이스으 ㅣ테이블 이름
paranoid: true로 설정하면 deleteAt이라는 컬럼이 생깁니다. 지운시간을 기록합니다.
아래와 같은 방식으로도 모델을 정의 할 수 있습니다.
module.exports = (sequelize, DataTypes) => {
return sequelize.define('Model_name', {
// 열 (Column) 정의
_id: { // 열 이름
type: DataTypes.INTEGER, // 자료형
primaryKey: true, // Primary Key 여부
autoIncrement: true, // 자동증가 여부
comment: '문제 고유 ID', // 설명
},
question: { // 열 이름
type: DataTypes.STRING(200), // 자료형
allowNull: false, // Null 혀용 여부
comment: '문제', // 설명
}
});
}
migration 파일을 통해서 DB에 테이블을 생성할 수 있습니다. 이 파일들은 DB의 변경점에 대한 commit입니다. DB의 경우 덮어쓰기가 불가능하기 때문에, 사용자가 스스로 이전 DB구조에서 새로운 DB 구조로 변경하는 방법을 정의해줘야합니다.
즉 스키마의 수정이 이루어질 떄 마다 이력을 저장해 스키마 수정이력을 관리할 수 있고, 모델만 작성하면 DB에 테이블을 작성할 수 있습니다.
up: 이전 DB 구조에서 다음 DB구조로 변경하는 방법을 포함하는 함수입니다. DB 구조의 변경은 테이블의 생성, 테이블 열의 추가, 테이블 열 DataType의 변경등이 있습니다.
down: up이 수행한 작업을 취소시킬 수 있는 방법을 정의합니다.테이블의 생성일 경우 반대로 테이블의 삭제, 열의 추가일 경우 열의 삭제, DataType의 변경일 경우 이전 DataType으로 재변경을 정의하게 됩니다.
Migration 실행
npx sequelize-cli db:migrate
테이블에 정의된 부분이 migrate됩니다
npx sequelize-cli db:migrate:undo
seed 서버가 시작될 때 애플리케이션이 가지고 있어야할 정적인 데이터들을 DB에 추가해주는 기능을 의미합니다
npx sequelize-cli seed:generate --name demo--이름
npx sequelize-cli db:seed:all
npx sequelize-cli db:seed:undo:all
npx sequelize-cli seed:generate --name test
test는 파일이름 입니다.
파일을 열어보면 migration과 똑같은 구조입니다.
https://m.blog.naver.com/jhc9639/220967034588