Sequelize
Sequelize
는 Node에서 데이터베이스 접속시 편리하게 작업할 수 있도록 도와주는 라이브러리입니다. ORM
(Object-relational Mapping)으로 자바스크립트 객체와 데이터베이스 릴레이션을 맵핑해 주고 자바스크립트 구문을 알아서 SQL로 바꾸어 질의하기 때문에 SQL 문법을 몰라도 데이터베이스를 다룰 수 있게 도와줍니다. 더욱이 MySql, MariaDB, PostgreSQL, SQLite, MSSQL
등 다른 데이터베이스도 같이 쓸 수 있기 때문에 유용하게 활용할 수 있습니다.
Sequelize 설치
Sequelize
와 mysql
을 설치하고 sequelize 커맨드를 사용하기위해 sequelize-cli
를 전역으로 설치합니다. 설치 완료후 sequelize init
명령어를 실행해 줍니다.
1 2 3 npm i sequelize mysql2npm i -g sequelize-clisequelize init
Model 생성
sequelize init
명령으로 생성된 models/
폴더에 sequelize.define
메소드를 사용하여 mysql table과 대응되는 sequelize model을 추가해 줍니다.
sequelize는 기본적으로 model이름은 단수로 생성하며, 단수 모델명의 복수형 이름을 테이블 명으로 사용합니다. 그리고 id를 기본키로 연결하므로 id컬럼을 추가할 필요는 없습니다.
1 sequelize.define ('modelName' , column, option);
models/user.js
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 module .exports = ({sequelize, DataTypes = Sequelize} ) => { return sequelize.define ( 'user' , { name : { type : DataTypes .STRING (20 ), allowNull : false , unique : true , }, age : { type : DataTypes .INTEGER .UNSIGNED , allowNull : false , }, created_at : { type : DataTypes .DATE , allowNull : false , defalutValue : sequelize.literal ('now()' ), } }, { timestamps : false } ) };
dataType
sequelize.define를 사용하여 column 선언시 속성의 dataType은 SQL문 dataType과는 조금 다른 이름으로 선언합니다.
VARCHAR: STRING
INT: INTEGER
UNSIGNED 옵션이 적용된 INT: INTEGER.UNSIGNED
ZEROFILL옵션: INTEGER.UNSIGNED.ZEROFILL
TINYINT: BOOLEAN
DATETIME: DATE
NOT NULL: allowNull
UNIQUE: UNIQUE
기본값: defaultValue
options
timestamps : true 일 경우 createdAt, updatedAt 컬럼을 자동으로 추가하고 row가 생성, 수정될 때 시간이 자동으로 입력됩니다.
paranoid : timestamps 가 true 경우에만 사용가능합니다. deletedAt 이라는 컬럼이 추가되며 row 삭제하는 sequelize 명령 내릴 경우 deletedAt에 제거 날짜를 입력합니다.
underscored : sequelize가 자동으로 생성해주는 컬럼명을 스네이크 형식으로 변경합니다. createdAt, updatedAt, deletedAt 컬럼을 각각 created_at, updated_at, deleted_at으로 변경해 줍니다.
tableName : sequelize는 자동으로 define 메소드 첫번째 인자(모델명)를 복수형으로 만들어 테이블명으로 사용합니다. 테이블 명을 다른 것으로 지정하고 싶을 때 해당 옵션을 사용합니다.
Model 간 관계 선언
아래 메소드들을 사용하여 table에 해당하는 model간 관계를 맺어줍니다.
doc associations
HasOne : One-to-one association
HasMany : One-to-many association
BelongsTo : One-to-one association
BelongsToMany : Many-to-many association with a join table.
1:1
1:1 경우 hasOne, belongTo가 반대여도 상관없습니다.
1 2 db.User .hasOne (db.Info , { foreginKey :"user_id" , sourceKey :"id" }); db.Info .belongTo (db.User , { foreginKey :"user_id" , tarketKey :"id" });
1:N
foreginKey 를 사용하여 관계를 맺어줄 경우 hasMany는 sourceKey, belongTo는 targetKey를 사용합니다.
1 2 User .hasMany (Comment , { foreginKey :"commenter" , sourceKey : "id" }); Comment .belongTo (User , { foreginKey :"commenter" , targetKey : "id" });
N:M
새로운 릴레이션으로 사용될 이름을 through 속성의 값으로 넣어줍니다.
1 2 Post .belongToMany (HashTag , { through :"PostHashTag" });HashTag .belongToMany (Post , { through :"PostHashTag" });
설정 및 데이터베이스 연동
config/config.json
데이터베이스 연동을 위한 정보를 담을 config 파일을 생성합니다.
1 2 3 4 5 6 7 8 9 10 11 12 { "development" : { "username" : "root" , "password" : "password" , "database" : "nodejs" , "host" : "127.0.0.1" , "dialect" : "mysql" , "operatorsAliases" : false } , "production" : { ...} , "test" : { ...} }
models/index.js
sequelize init
명령으로 생성된 models/index.js
파일을 열어 수정합니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 const path = require ('path' );const Sequelize = require ('sequelize' );const env = process.env .NODE_ENV || 'development' ;const config = require ('../confing/config' )[env];const db = {};const sequelize = new Sequelize ( config.database , config.username , config.password , config ); db.sequelize = sequelize; db.Sequelize = Sequelize ; db.User = require ('./user' )(db); db.Post = require ('./post' )(db); db.User .hasMany (db.Post ); db.Post .belongsTo (db.User ); module .exports = db;
model/index.js
에서 config.json
파일을 불러와 sequelize 인스턴스를 생성하고 정의된 model
간 관계를 선언합니다.
app.js
sequelize.sync()
메소드를 호출하여 데이터베이스완 연동합니다.
1 2 3 const sequelize = require ('./models' ).sequelize ;const app = express ();sequelize.sync ();
CRUD
findAll, destroy, update 같은 메소드들을 사용하여 database에 질의할 수 있습니다. 좀 더 자세한 사용은 아래 링크를 참조해 주세요.
doc querying
조회 Option 객체
attribute
where
order
limit : // find 메소드랑 동일
offset
Sequelize Op 연산자
Op.gt : 초과
Op.gte : 이상
Op.lt : 미만
Op.lte : 이하
Op.ne : 같지않음
Op.or: 또는
Op.in : 배열 요소중 하나
Op.notln: 배열 요소와 모두 다름
Controller 사용 예
routes/index.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 const express = require ('express' );const User = require ('../models' ).User ;const router = express.Router ();router.get ('/' , async (req, res, next) => { try { const users = await User .findAll (); res.render ('viewTemplate' , {users}); } catch (error) { next (error); } }); module .exports = router;
READ
1 const { User , Sequelize : { Op } } = require ('../models' );
1 2 3 4 5 User .find ({}) User .findAll ({ limit : 1 });
1 2 3 4 User .findAll ({ attribute : ['name' ,'married' ], });
1 2 3 4 5 6 7 8 9 User .findAll ({ attribute : ['name' ,'married' ], where : { married : 1 , age :{ [Op .gt ]: 30 }, }, order : [['age' ,'DESC' ]] });
1 2 3 4 5 6 7 8 User .findAll ({ attribute : ['name' ,'married' ], where : { [Op .or ]: [{ married : 0 }, { age : { [Op .gt ]: 30 } } }, order : [['age' ,'DESC' ]] });
N:M 관계에서 테이블 조회(get, set, add + 모델명의 복수형 메소드 사용 가능)
1 2 3 4 async (req, res, next) => { const tag = await HashTag .find ({ where : { title : "dev" } }); const post = await tag.getPosts (); };
UPDATE
1 2 3 4 5 6 7 8 9 10 11 12 13 14 User .update ({ column : "바꿀내용" },{ where : { id : 2 } }); `` `` ### DELETE `` `javascript // DELETE FROM db.users WHERE id=2; User.destroy({ where: { id: 2 } });
Sequelize는 ORM으로써 편리하게 사용할 수 있지만 모델링 및 SQL 문에 대한 이해를 가지고 사용하는 것이 좋을 것 같습니다. 좀 더 자세한 사용법은 Sequelize API 문서를 참고해 주세요.