sequelize를 이용한 테이블 join
- include를 이용하면 된다.
(공식문서 url : https://sequelize.org/master/manual/eager-loading.html)
ex) 2개의 테이블이 존재 / posts, images라는 테이블
--> images라는 테이블이 posts테이블의 PK를 postid라는 FK로 참조하는 관계
--> posts와 images는 1:N 관계
--> 위에서는 posts테이블에 4개의 데이터가 담겨있지만 JOIN하게 되면 id=1인 행은 images테이블에서 3개의 데이터가 해당 id를 FK로 참조하고 있다.
--> posts테이블에서 id=1인 행은 images테이블의 3개의 행과 연관이 있게 된다.
--> 즉 posts테이블에서 id=1인 행, images 테이블 3개의 행 / posts테이블에서 id=2인 행, images 테이블 2개의 행
posts테이블에서 id=3인 행, images 테이블 1개의 행 / posts테이블에서 id=4인 행, images 테이블 2개의 행
위 같은 관계를 형성하게 되어 JOIN테이블이 형성된다.
- sequelize로 JOIN테이블 생성
1. findAll()로 우선 posts 테이블을 생성한 model수행
2. findAll()을 수행하면서 include를 이용하여 include에 지정된 model(테이블)과 조인된 결과 출력
ex) 코드 예시
// 여기서 post는 posts 테이블을 생성한 model, image는 images 테이블을 생성한 model
// include로 지정한 부분에서 model은 JOIN할 model명 / attribute는 JOIN할 테이블에서 조회할 컬럼명지정
// DB조회 결과를 얻기 위해서는 dataValues라는 키값으로 접근필요 / 배열의 각 요소를 지정해야 함(객체를 요소로 가진 배열 반환)
let postList = await post.findAll({
include: [{model : image, attributes: ['image'] }],
attributes: ['id', 'title', 'context', 'price', 'post_userid']
});
--> 실제 sequelize로 sql구문 적용
Executing (default): SELECT `post`.`id`, `post`.`title`, `post`.`context`, `post`.`price`, `post`.`post_userid`, `images`.`id` AS `images.id`, `images`.`image` AS `images.image` FROM `posts` AS `post` LEFT OUTER JOIN `images` AS `images` ON `post`.`id` = `images`.`postId`;
--> 출력결과는 우선 findAll()을 수행하였기 때문에 posts테이블의 모든 데이터가 조회되므로 현재 posts테이블에는 4개의 레코드(데이터)가 저장되어 있으므로 길이가 4인 배열이 반환 / 4개의 레코드가 각 요소
--> 그리고 4개의 각 요소와 관련이 있는 images테이블의 레코드(데이터)가 각 요소에 배열형태로 저장되어 있음
--> 즉 [ {id=1인 posts 레코드, images:[ {posts테이블의 id=1를 참조하고 있는 images레코드1}, {레코드2}, ...] },
{id=2인 posts 레코드, images:[ {posts테이블의 id=2를 참조하고 있는 images레코드1}, {레코드2}, ...] }},
...]
--> 즉 1:N의 관계를 가진 테이블을 sequelize에서 JOIN할 경우 우선 1의 관계를 가진 테이블을 배열로 구성후 각 배열의 요소에 N의
관계를 가진 테이블을 다시 배열의 형태로 넣음
--> 위에 예시에서는 posts테이블의 id=1을 참조하고 있는 images테이블의 레코드수는 3개이기 때문에 길이가 3인 배열이 images키의 value값으로 들어간다
--> 위의 예시에서는 1. posts테이블 레코드 수만큼의 길이를 가진 배열 생성
2. 위에 배열의 각 요소마다 해당 요소를 참조하는 images테이블 레코드 수만큼 길이를 가진 배열 생성
--> posts테이블에서 id=1인 행, images 테이블 3개의 행 / posts테이블에서 id=2인 행, images 테이블 2개의 행
posts테이블에서 id=3인 행, images 테이블 1개의 행 / posts테이블에서 id=4인 행, images 테이블 2개의 행
이런 관계를 형성하고 있기 때문에(posts테이블과 images테이블, 1:N관계) sequelize에서 include를 이용하여 JOIN한 결과는 아래와 같다
--> posts테이블과 images테이블 JOIN결과
[
{posts레코드1, images: [{posts레코드1과 연관된 images레코드1}, { images레코드2}, { images레코드3}] }
, {posts레코드2, images : [{posts레코드2과 연관된 images레코드1}, { images레코드2}] }
,{posts레코드3, images : [{posts레코드3과 연관된 images레코드1}] }
,{posts레코드4, images : [{posts레코드4과 연관된 images레코드1}, { images레코드2}] }
]