본문 바로가기
프로그래밍/database

시퀄라이즈로 테이블, 모델 생성하기, 관계정의하기

by 한코코 2022. 7. 17.

테이블과 모델 생성하기

mysql 테이블은 sequelize(시퀄라이즈) 모델과 같다.

시퀄라이즈는 테이블과 모델 사이를 연결해준다.

보통 테이블은 소문자 복수형(users), 모델은 대문자로 시작하는 단수형(User)로 작성한다.

 

 

 


테이블과 모델 설정하기

모델은 Sequelize.Model을 확장한 클래스로 선언한다.

모델은 두개의 메서드로 나뉜다.

 

 

테이블에 대한 설정을 하는 init 메서드

  • 첫번째 인자 : 테이블 컬럼에 대한 설정
  • 두번째 인자 : 테이블 자체에 대한 설정
  • 시퀄라이즈는 자동으로 id를 기본키로 연결한다.(작성할 필요없음)
  • 시퀄라이즈는 mysql에서 사용하는 자료형과 다른 자료형을 사용한다.
  • 시퀄라이즈 자료형에 대한 공식사이트 자료( https://sequelize.org/docs/v6/core-concepts/model-basics/#data-types )
const Sequelize = require("sequelize");

class User extends Sequelize.Model {
  static init(sequelize) {
    return super.init(
      {
        u_id: {
          type: Sequelize.STRING(64),
          allowNull: false,
          unique: true,
        },
      },{
        sequelize,
        timestamps: false, // true : createdAt,updatedAt컬럼 자동추가함
        underscored: false, // true : 카멜표기법을 스네이크표기법으로 바꿈
        modelName: "User",
        tableName: "users",
        paranoid: false, // true : deletedAt컬럼 자동추가, 로우 완전삭제가 되지않는다.
        charset: "utf8", // 한글입력설정, 이모티콘입력설정은 utf8mb4
        collate: "utf8_general_ci", // 한글입력설정, 이모티콘입력설정은 utf8mb4_general_ci
      }
    );
  }
  static associate(db) {
    // 다른 테이블과 관계를 맺고싶을때 작성
    // 예) 일대다, 다대다 같은 관계
  }
}

module.exports = User;

 

 

 


다른 모델과의 관계를 설정하는 associate 메서드

하나의 아이디에 여러개 덧글이 연결되어있는 일대다 같은 관계를 설정할때 작성한다.

따라서 associate 메서드를 사용하려면 다른 모델과의 관계를 알아야한다.

 

 

 

 

일대일 (1:1)

하나의 아이디에는 하나의 비밀번호가 연결되어있는 관계를 생각하면 편하다.

단, 주종관계에 따라 사용하는 메서드가 다르니 잘 구별해서 사용하자.

foreignKey에 이름을 설정해주지않는다면 자동적으로 모델명+기본키명이 이름이 된다.

'외래키컬럼'이라고 작성하지 않으면 아이디+id인 아이디Id(카멜표기법)가 이름이 된다.

static associate(db) {
    db.아이디.hasOne(db.비밀번호, { foreignKey: '외래키컬럼', sourceKey: 'id' });
}

static associate(db) {
    db.비밀번호.belongsTo(db.아이디, { foreignKey: '외래키컬럼', sourceKey: 'id' });
}

 

 

 

 

일대다 (1:N)

하나의 아이디가 여러개의 덧글을 작성하거나, 하나의 게시물에 여러개의 덧글이 달린다거나.

하나에 여러개가 종속될때 사용하는 관계다.

일대일관계 메서드와 비슷하지만 hasOne이 hasMany로 바뀐다.

static associate(db) {
    db.게시글.hasMany(db.덧글, { foreignKey: '외래키컬럼', sourceKey: 'id' });
}

static associate(db) {
    db.덧글.belongsTo(db.게시글, { foreignKey: '외래키컬럼', sourceKey: 'id' });
}

 

일대다 (1:N) 관계에 접근해서 정보 가져오기

위에서 아이디와 덧글을 일대다(hasMany-belongsTo)관계로 설정했었다.

특정 사용자와 특정 사용자가 작성한 덧글들까지 가져오고 싶다면 다음과 같이 작성하면 된다.

include를 사용하는 방법과 자동적으로 모델이름 앞에 붙어서 생성되는 메서드를 사용할 수 있다.

시퀄라이즈는 자동적으로 생성되는 다음과 같은 메서드를 지원한다.

  • get+모델명+s : 조회
  • set+모델명+s : 수정
  • add+모델명 : 한개 추가
  • add+모델명+s : 여러개 추가
  • remove+모델명+s : 삭제
const user = await 아이디.findOne({
	include:[{
    	model:'덧글'
    }]
})

// 또는
const user = await 아이디.findOne({})
const comment = await user.get덧글()

 

 

 

 

 

 

 

다대다 (N:M)

여러개의 태그가 여러개의 게시물에 달리는 관계이며 서로 종속되지 않는다.

서로 belongsToMany 메서드를 사용한다.

게시물과 태그를 짜맞춘 정보가 필요하기때문에 새로운 모델이 생성되며,

이 모델의 이름은 through에 적은 '관계'가 된다.

        게시물    |        관계       |      태그
------------------------------------------------------
1번P #사과 #바나나      1번P 1번태그          1번태그 사과
                     1번P 2번태그          2번태그 바나나
------------------------------------------------------
2번P #바나나           2번P 2번태그          3번태그 귤
------------------------------------------------------
3번P #귤              3번P 3번태그
db.게시물.belongsToMany(db.해시태그, { through: '관계' });
db.해시태그.belongsToMany(db.게시물, { through: '관계' })

 

알아보기 쉽도록 1번P나 1번태그로 작성했지만 원래 이 자리에는 시퀄라이즈가 자동으로 생성해주는 id가 들어간다.

다대다에서 데이터를 조회할때는 조금 복잡한 흐름이 생긴다.

#사과란 해시태그를 사용한 게시물을 조회할경우

  1. #사과를 사용한 태그 모델에서 검색
  2. #사과의 아이디값인 1을 가져옴
  3. 관계 모델에서 태그아이디가 1인 게시물 아이디들을 찾음.
  4. 찾은 게시물 아이디을 게시물 모델에서 검색해서 데이터 가져옴.
        게시물    |        관계       |      태그
------------------------------------------------------
1 #사과 #바나나      	1 1           	1 사과
                  	1 2           	2 바나나
------------------------------------------------------
2 #바나나           	2 2           	3 귤
------------------------------------------------------
3 #귤              	3 3

 

 

 

 

 

 

작성한 모델 끌어와서 사용하기

// model/index.js
const Sequelize = require("sequelize");
const User = require('./users')

const env = process.env.NODE_ENV || "development";
const config = require("../config/config")[env]; // 데이터베이스 설정을 불러옴
const db = {};

// 데이터베이스 - mysql 연결
const sequelize = new Sequelize( // 새 시퀄라이즈 객체를 만들어서
  config.database, // 불러온 데이터베이스(mysql)과 연결한다.
  config.username,
  config.password,
  config
);

db.sequelize = sequelize; // 재사용을 위해서 db.sequelize에 저장

db.User = User //db에 User객체 저장
User.init(sequelize) // User의 init 메서드 실행 -> 테이블이 모델과 연결됨
User.associate(db) // User의 associate 메서드 실행 -> 다른 테이블과의 관계적용

module.exports = db;

 

 

 

 

 


모델 이름을 바꾸고 싶을때 (as)

이렇게 이름을 바꾸면 사용했던 객체들도 자동으로 모델명이 바뀐다.

static associate(db) {
    db.게시글.hasMany(db.덧글, { foreignKey: '외래키컬럼', sourceKey: 'id', as:'ChangeName' });
}

 

이것 외에 시퀄라이즈 쿼리들은 여기에 정리.

 

댓글