sequelize 는 node.js의 ORM 라이브러리중 하나로 여러 RDBMS를 지원하고 Promise 기반으로 구현되었기 때문에 비동기 로직을 편리하게 작성할 수 있게 한다.
sequelize 설정 (model/index.js)
const Sequelize = require('sequelize');
const env = process.env.NODE_ENV || 'development';
const config = require('../config/config')[env];
const db = {};
const sequelize = new Sequelize(config.database, config.username, config.password, config);
db.User = require('./user')(sequelize, Sequelize)
db.Post = require('./post')(sequelize, Sequelize)
db.Hashtag = require('./hashtag')(sequelize, Sequelize)
db.Comment = require('./comment')(sequelize, Sequelize)
db.Image = require('./image')(sequelize, Sequelize)
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
module.exports = db;
1. env 파일에 정의한 DB의 커넥션 정보를 가져와서 Sequelize의 객체 생성시 인자로 부여한다 (커넥션 연결)
2. db라는 객체를 만든 후 모델(Entity)로 정의한 js를 지정한다.
3. db안에 들어온 모델을 루프돌면서 연관관계를 맺어준다.
Model
module.exports = (sequelize, DataTypes) => {
const User = sequelize.define('User',{
email: {
type: DataTypes.STRING(30),
allowNull: false,
unique: true,
},
nickname : {
type: DataTypes.STRING(20),
allowNull: false,
},
password: {
type: DataTypes.STRING(100),
allowNull: false,
},
},{
charset: 'utf8',
collate: 'utf8_general_ci'
});
User.associate = (db) => {
db.User.hasMany(db.Post,{as: 'Posts'});
db.User.hasMany(db.Comment);
db.User.belongsToMany(db.Post, {through: 'Heart', as: 'Hearted'})
db.User.belongsToMany(db.User, {through: 'Follow', as: 'Followings', foreignKey: 'FollowerId'})
db.User.belongsToMany(db.User, {through: 'Follow', as: 'Followers', foreignKey: 'FollowingId'})
};
return User;
}
1. model.export 함수는 스프링의 auto-ddl-create와 같은 역할을 하는 함수이며 difine함수의 두번째 인자로 컬럼의 데이터 타입과 옵션을 지정할 수 있다.
2. id 필드 같은 경우 데이터베이스의 PK 전략을 따른다.
3. associate 함수 같은 경우 Entity간 연관관계를 정의하는 함수이다.
1:N 연관관계
- hasMany 는 해당 모델에 1:N 구조의 연관관계를 지정하는것을 말하며 Spring JPA의 @OneToMany와 유사하다.
- as를 사용하여 리스트에 대한 별칭을 지정할 수 있으며 as가 생략된 경우 복수형으로 바뀌어 정의된다.
N:1 연관관계
- belongsTo 로 정의 하며 N:1 구조로 연관관계를 맺는다. Spring JPA의 @ManyToOne 과 유사하며
- N:1 연관관계의 특성에 맞게 FK를 갖도록 테이블이 구성된다.
N:N 연관관계
- belongsToMany 로 정의하며 N:N의 구조로 연관관계가 구성된다. Spring JPA의 @ManyToMany와 유사하며
- 자동으로 중간테이블이 생성된다. 테이블의 명칭도 지정할 수 있으며 FK의 지정도 가능하다.
- 의미 있게 사용하려면 중간테이블 모델을 따로 빼는게 맞을 것 같다.(JPA에서는 그렇게 사용했었음)