-
*시퀄라이저를 사용하고 있는 환경에서
관계 쿼리는 결괏값이 자바스크립트 객체이다.
만약에 사용자를 가져온다~ 라고 하면 다음과 같다
const user = await User.findOne({}); //모두 가져올거면 findAll console.log(user.nick); //사용자 닉네임
user에 유저 한 명을 찾아서 할당을 했고 출력문을 통해 그 유저의 닉네임에 접근했다. 결괏값이 자바스크립트 객체여서 가능한 일이다.
include로 JOIN 과 비슷한 기능 수행 가능(관계 있는 것 엮을 수 있음)
만약에 내가 쓴 댓글까지 가져오고 싶다면 어떻게 할까?
SQL에서는 조인을 사용해야 하지만 시퀄라이저에서는 User.findOne 한 다음에 include에 Coomment를 넣어주면 된다.
const user = await User.findOne({ include: [{ model: Comment, }] }); console.log(user.Comments); //사용자 댓글
사용자를 가져오면서 그 사용자가 작성했던 댓글까지 함께 가져온다.
출력문에서는 Comments로 복수형이 쓰였는데 그 이유는 hasMany이기 때문이다. hasOne이면 Comment로 자동으로 바뀌게 된다.
시퀄라이저가 어떤 관계형인지에 따라서 자동으로 변환해 준다.
다대다 모델은 다음과 같이 접근이 가능하다
db.sequelize.models.PostHashtag
get+모델명으로 관계 있는 데이터 로딩 가능
const user = await User.findOne({}); const comments = await user.getComments(); console.log(comments); //사용자 댓글
유저를 가지고 와서 getComments()를 하면 그 사용자가 작성했던 모든 댓글들을 다 가지고 올 수 있다. 위에서 include하는 방법과는 또 다른 방식으로 가지고 온 것이다.
*단, include를 사용하면 성능상 문제가 생길 수 있다. 이유는 동시에 가져오는 것이기 때문에 db가 좀 더 일을 많이 해야하기 때문이다.
as로 모델명 변경 가능
//관계를 설정할 때 as로 등록 db.User.hasMany(db.Comment, { foreignKey: 'commenter', sourceKey: 'id', as: 'Answers'}); //쿼리할 때는 const user = await User.findOne({}); const comments = await user.getAnswers(); console.log(comments); //사용자 댓글
만약에 getComments(), 또는 user.Comments 부분을 좀 바꾸고 싶다~ 하면 as로 바꿀 수 있다.
as를 써서 getAnswers() 로 바뀐 것을 볼 수 있다.
*include를 사용해도 마찬가지이다. 다만, 모델을 기입하는 자리에는 실제 모델의 명이 와야한다.
const user = await User.findOne({ include: [{ model: Comment, }] }); console.log(user.Answers); //사용자 댓글
실제로 가져올 때만 실제하는 모델명을 사용하고 출력할때만 as로 바꾼 부분으로 출력한다.
*오히려 햇갈릴 수 있으니 자주 쓰는 것은 별로 추천하지 않는다.
include나 관계 쿼리 메서드에도 where나 attributes 사용 가능하다
const user = await User.findOne({ include: [{ model: Comment, where: { id: 1, }, attributes: [id], }] }); //또는 const comments = await user.getComments({ where: { id: 1, }, attributes: ['id'], });
여기서 where는 댓글에서의 where이다.
어떤 사용자의 댓글을 가져오는데 댓글의 id가 1인 것만 가져와라~ 하는 코드이다.
*어떤 사람의 댓글을 가져오는데 그 사용자의 id가 1이어야 한다~ 와는 매우 다른 것이기 때문에 where절이 어디에 적용되는지가 매우 중요하다. 이것을 원할 경우 include 밖에다 where을 써 주면 된다.
attributes는 댓글에 속성이 여러 개 있을 수 있는데 그 중 id만 가지고 오겠다~ 라는 뜻이다.
만약 사용자의 아이디만 가지고 오고 싶으면 include 밖에서 attributes를 사용하면 된다.
생성 쿼리
const user = await User.findOne({}); const comment = await Comment.create(); await user.addComment(comment); //또는 await user.addComment(comment.id);
사용자를 먼저 만들고 빈 댓글을 만들었다.
이후에 add를 이용해서 user에 댓글을 할당했다.
이렇게 하면 사용자와 댓글하고 연결이 되서 저장이 된다.
여러 개를 추가할 때는 배열로 추가 가능
const user = await User.findOne({}); const comment1 = await Comment.create(); const comment2 = await Comment.create(); await user.addComment([comment1, comment2]);
배열로 여러 개를 추가한다.
수정은 set+모델명, 삭제는 remove+모델명이다.
원래 쿼리에서는
create
find
update
destroy
관계 쿼리에서는
add
get
set
remove
단어들이 조금 다른 것을 볼 수 있다.
관계 쿼리와 일반 쿼리의 동사명이 조금 다르다~ 라는 점을 알고 넘어가자
raw 쿼리
직접 SQL을 쓸 수 있다.
const [result, metadata] = await sequelize.query('SELECT * FROM comments'); console.log(result);
raw쿼리를 이용하면 직접 위와 같은 방법으로 SQL을 직접 쓸 수 있다.
'노드' 카테고리의 다른 글
노드 데이터베이스 CRUD 작업하기 (0) 2023.04.18 노드 데이터베이스 MySQL (1) 2023.04.18 노드 테이블 관계 이해하기 (0) 2023.04.18 노드 next 활용법 (0) 2023.04.17 노드 미들웨어 특성 이해하기 (0) 2023.04.17