본문 바로가기
개발 Study/GraphQL

[GraphQL] GraphQL 사용법 - (3) Sequelize 사용하기(1:1, ForeignKey, Join)

by jiyoon_92 2022. 9. 30.
반응형

Sequelize 테이블 연결 및 외래키 사용

GraphQL

 

1. Sequelize 테이블 관계

테이블 관계는 1:1, 1:N, M:N 이 있는데 foreignkey를 이용하여 서로 관계를 맺으며 join을 통해 연결된 테이블의 정보까지 불러올 수 있다.

참조 : https://sequelize.org/docs/v6/core-concepts/assocs/

 

Associations | Sequelize

Sequelize supports the standard associations: One-To-One, One-To-Many and Many-To-Many.

sequelize.org

A.hasOne(B, { /* options */ }); // A는 한 개의 B를 갖는다. A : B = 1 : 1
A.belongsTo(B, { /* options */ }); // A는 B에 종속된다. 1:1 관계로, B의 외래키를 이용한다.
A.hasMany(B, { /* options */ }); // A는 여러개의 B를 갖는다. A : B = 1 : N  1:N의 관계로 B의 외래키를 이용한다.
A.belongsToMany(B, { through: 'C', /* options */ }); A는 여러개의 B에 종속된다 . A : B = M : N C를 통해서.

1-1. 1:1 관계 만들기

1:1관계를 만들기 위해서는 A.hasOne(B)와 A.belongsTo(B)를 둘 다 써줘야 한다. sequelize에서 모델명을 통해 각 모델을 가져온다.

Member모델의 member_id는 자동증가 키로 primaryKey다.  Member-Person은 member_id를 통해 연결되어 있으며 1:1 관계다. Member-Academy도 마찬가지로 member_id를 통해 연결되어 있으며 1:1관계다. Person, Academy Model을 생성할 때 member_id를 primaryKey:true로 반드시 설정해둔다. 그런 다음 아래와 같이 foreignKey에 member_id를 넣어주며, Member 모델의 primaryKey인 member_id를 외래키로 다른 테이블들과 연결해준다. hasOne의 옵션에도 belongsTo의 옵션에도 foreignKey를 넣어줘야 정상적으로 작동한다.

    public static initAssociations() {
      const sequelize = this.getInstance();
      const m_member = sequelize.model("member");
      const m_person = sequelize.model("person");
      const m_academy = sequelize.model("academy");
      m_member.hasOne(m_academy, {foreignKey: "member_id"});
      m_academy.belongsTo(m_member, {foreignKey: "member_id"});
      m_member.hasOne(m_person, {foreignKey: "member_id"});
      m_person.belongsTo(m_member, {foreignKey: "member_id"});
    }

그리고 종속되는 모델 (Person | Academy)의 ColumnOption에 reference를 이용하여 외래키를 설정해 준다.

@Column({ type: DataTypes.INTEGER, primaryKey:true, references: { model:'member', key:'member_id' } })
  member_id!: number; //회원id

N:M의 관계는 개발 진도가 나가면 직접 해본 후 글에 추가하도록 하겠다.


2. Sequelize 테이블 Join 하기

Member테이블의 정보를 받을 때 종속된 테이블인 Person이나 Academy의 정보까지 받아오고 싶을 땐 include 옵션을 추가하여 받아온다. include에 Array 형태로 연결된 여러 테이블들을 등록할 수 있으며, 각각 옵션을 이용해 attribute(가져올 필드 정하기)나 exclude(제외할 필드 정하기)로 좀 더 디테일하게 구현할 수 있다. 나는 GraphQL을 통해 원하는 정보만 얻을 거기 때문에 그냥 default 값으로 테이블의 전체 필드 정보를 받아올 수 있도록 했다.

반응형
const getItems = async () => {
  const members = await Member.findAll({include: [{model : Person}, {model : Academy}]});
  console.log(members);
  return {res : true, msg : `All members found.`, data : members};
};

const getItemByUserId = async (user_id : string) => {
  const member = await Member.findOne({where : { user_id : user_id}, include : [{model : Person}, {model : Academy}]});
  if (!member)
  {
    throw Error(`member not existed. id: ${user_id}`);
  }
  return {res : true, msg : `${user_id} found.`, data : [member]};
}

3. GraphQL Schema에 종속 테이블 타입 추가하기

맨 마지막 부분에 person과 academy를 Nullable로 추가해준다.

#import Person from "person.graphql"
#import Academy from "academy.graphql"
type Member {
    member_id: Int!
    user_id: String!
    password: String!
    member_type: String!
    reg_date: String
    reg_type: String!
    reg_channel: String!
    member_status: String!
    info_period: String!
    sms_receive: Boolean!
    email_receive: Boolean!
    password_date: String
    rest_date: String
    out_date: String
    person: Person
    academy: Academy
}

4. GraphQL Query문 수정하기

Client 부분에서는 다음과 같이 Query문을 수정하면 person이나 academy의 정보까지 가져올 수 있다.

user_id를 이용하여 해당되는 member의 정보를 불러오는 쿼리다.

 query($user_id : String!) {
        getMemberById(user_id : $user_id) {
        res
        msg
        data {
            member_id
            user_id
            password
            member_type
            reg_date
            reg_type
            reg_channel
            member_status
            info_period
            sms_receive
            email_receive
            password_date
            rest_date
            out_date
            person {
                name
                byname
                sex
                birthday
                handphone
                post_num
                address
                address_detail
                email
                notice
            }
            academy {
                name
                company_num
                post_num
                address
                address_detail
                area_id
                tel_num
                ceo_name
                staff_name
                staff_handphone
                email
                start_date
                type
                main_target
                main_subject
                student_count
                logo
                homepage
            }
        }
    }
 }

다음과 같은 결과를 받을 수 있다.

Response


2022.09.27 - [개발 Study/Node, js, react] - [GraphQL] GraphQL 사용법 - (1) Schema 생성 후 ApolloServer 연동하기

 

[GraphQL] GraphQL 사용법 - (1) Schema 생성 후 ApolloServer 연동하기

GraphQL + ApolloServer 1. GraphQL 타입 선언 (Schema 만들기) 1-1. Query 타입 Query 타입은 보통 fetch data를 하여 원하는 정보를 얻어올 때 쓰인다. schema.graphql을 만든 후 Schema에 Query 타입을 선언..

chuun92.tistory.com

2022.09.29 - [개발 Study/Node, js, react] - [GraphQL] GraphQL 사용법 - (2) Sequelize + MSSQL 연동

 

[GraphQL] GraphQL 사용법 - (2) Sequelize + MSSQL 연동

Sequelize + MSSQL 1. Sequelize란? Node 에서 자주 사용되는 ORM 라이브러리다. ORM(Object-Relational Mapping)이란 관계형 데이터베이스와 자바스크립트 객체를 서로 연결해주는 도구로 좀 더 DB작업을 쉽게..

chuun92.tistory.com

 

현재 테스트중이라 1:1관계로만 만들어봤지만 추후 좀 더 복잡한 관계를 구현하고 Sequelize에서 지원하는 많은 옵션들을 적용해볼 예정이다. 적용하는대로 관련 정보는 포스팅해야지~!

오늘도 열코딩 화이팅

반응형

댓글