Sequelize 테이블 연결 및 외래키 사용
1. Sequelize 테이블 관계
테이블 관계는 1:1, 1:N, M:N 이 있는데 foreignkey를 이용하여 서로 관계를 맺으며 join을 통해 연결된 테이블의 정보까지 불러올 수 있다.
참조 : https://sequelize.org/docs/v6/core-concepts/assocs/
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
}
}
}
}
다음과 같은 결과를 받을 수 있다.
2022.09.27 - [개발 Study/Node, js, react] - [GraphQL] GraphQL 사용법 - (1) Schema 생성 후 ApolloServer 연동하기
2022.09.29 - [개발 Study/Node, js, react] - [GraphQL] GraphQL 사용법 - (2) Sequelize + MSSQL 연동
현재 테스트중이라 1:1관계로만 만들어봤지만 추후 좀 더 복잡한 관계를 구현하고 Sequelize에서 지원하는 많은 옵션들을 적용해볼 예정이다. 적용하는대로 관련 정보는 포스팅해야지~!
오늘도 열코딩 화이팅
'개발 Study > GraphQL' 카테고리의 다른 글
[GraphQL/Typescript] GraphQL로 이미지 파일 업로드하기 (1) | 2022.12.14 |
---|---|
[GraphQL] GraphQL 사용법 - (4) ThunderClient로 API 테스트하기 (0) | 2022.10.04 |
[GraphQL] GraphQL 사용법 - (2) Sequelize + MSSQL 연동 (1) | 2022.09.29 |
[GraphQL] GraphQL 사용법 - (1) Schema 생성 후 ApolloServer 연동하기 (2) | 2022.09.27 |
[GraphQL] GraphQL과 REST (2) | 2022.09.21 |
댓글