sequelize 사용하기2 -외래키, join, 함수들

codeing999·2022년 8월 4일
0

Sequelize 사용 일지

목록 보기
2/10

sequelize는 models나 migration이나 쿼리함수들 검색을 해봐도
왜 다 클래스 형태나 파일구조가 제각각인 글들이 나오는지 모르겠다.
그래서 그중에 뭘 적용해야 맞는지를 모르겠다.

그래서 모델, 마이그래이션 쓰기 귀찮아서 워크벤치로 관리해줬었는데
쿼리함수는 모델객체들을 보고 실행되기에 대충 작성할 수도 없었다.
그리고 JOIN쿼리를 하기 위해서 그 모델객체들의 1:N 관계나 외래키 등의 관계를 제대로 적용하려면 마이그레이션도 결국엔 제대로 써야했다.

외래키, Join

그래서 오래오래 찾다가 결국에 외래키 관계 작성하는 법을 알아냈다.
npx sequelize model:generate --name User --attributes email:string,nickname:string,password:string
이런식으로 테이블 속성들 처음부터 다 넣어준다음에 나중에 모델에 내손으로 외래키 내용 추가하려면 귀찮으니까
일단 기본적인 속성만 몇개 적어서 테이블을 만들었다. 그리고 그 후에 마이그레이션으로 참조 관계를 자세하게 작성한 속성을 추가하기로 했다.

await queryInterface.addColumn(
      'like',
      'fk_note_id', 
      {
        type: Sequelize.INTEGER,
        references: {
          model: 'note',
          key: "noteid"
        }
      }
    );

이게 마이그레이션 파일의 컬럼을 추가하는 함수 부분이다.
like라는 테이블에 fk_note_id라는 컬럼을 추가하는데 그거의 타입은 integer이고
참조는 note라는 모델(테이블)을 참조하는데 note테이블의 noteid를 참조한다.

이렇게 마이그레이션을 작성해준다고 끝이 아니다.
models안에서도 뭔가를 해야하는데 삽질한 과정까지 써보자면,

fk_note_id: {
      type: DataTypes.INTEGER,
    },

like 모델의 fk_note_id에 외래키를 써줘야할거같지만 외래키관계 만드는데 성공한 후에도 여기는 그냥 이거만 써져있다. 여기가 아니다.

static associate(models) {
      Like.belongsTo(models.User);
      Like.belongsTo(models.note);
    }

그러면 like 모델 클래스 안의 저 associate 함수 안에 associate라는 이름답게 다른 모델과의 관계성을 적어놓으면 될거같지만 이거도 아니다.
여기 적어도 소용이 없었다.

답은 models의 index.js에 명시하는 것이었다.

db.User = require('./user.js')(sequelize, Sequelize);
db.Note = require('./note.js')(sequelize, Sequelize);
db.Comment = require('./comment.js')(sequelize, Sequelize);
db.Like = require('./like.js')(sequelize, Sequelize);

db.Note.hasMany(db.Like);
db.Like.belongsTo(db.Note, {
  foreignKey: "fk_note_id"
});
db.User.hasMany(db.Like, { as: "L" });
db.Like.belongsTo(db.User, {
  foreignKey: "fk_user_id",
  as: "userid"
});

일단 모델들을 다 임포트 해주고
그 모델들 관의 관계를 저렇게 적어준다.
1:N 관계인거 중에 1이거를 A N인거를 B라고 하면
A.hasMany(B);
B.belongsTo(A, {~}
이런식으로 둘의 관계를 작성하고 {}안에 like의 fk_note_id가 포린키임을 명시한다.

이렇게 작성하니까 드디어 join 쿼리가 작동했다.

 const LIKENOTES = await Like.findAll({  //좋아요 한게 없으면 []
     include : [{
         model:Note,
         attributes:['title', 'content', 'createdAt', 'updatedAt', 'like'],
     }],
     attributes:['fk_user_id', 'fk_note_id'],
     raw:true //raw값이 true이면 dataValues부분만 리턴.
 });   

join 쿼리는 이런식으로 작성했다.
사실 위의 migration이나 models부분이나 이 쿼리문에서나 별명을 붙일 수 있는 문법들이 있었는데
예를들면 Not as N 이런거
이런 기능들을 쓰니까 또 뭔가 에러가 나서 빼버렸다.
아무튼 조인의 역할을 하는건 include라는 저 구문이고.
밖에 있는게 꼭 N이나 1이거나하는 조건은 없고 둘이 참조관계만 되어있으면 된다.

함수들

SELECT 쿼리문

findAll()

const comment = await Comment.findAll({
            order : [
                ['createdAt', 'desc']
            ],
            where: {
                fk_note_id : commentDto.noteid
            }
        });

findOne()
findByPk()

 const author = await Comment.findByPk(req.params.commentid);

INSERT 쿼리문

create()

const comment = await Comment.create({
                fk_note_id : commentDto.noteid,
                fk_user_id : commentDto.userid,
                content : commentDto.content

            }

UPDATE 쿼리문

update()

const comment = await Comment.update({
            content : commentDto.content

            }, {
            where : {
                commentid : commentDto.commentid
                }
            }
        )

리턴값 : affectedRows를 리턴하는 것 같다. [1]이 리턴되면 테이블의 1행이 영향받았단 것이므로 성공. [0]이나 [2]나 기타 등등이라면 실패.

DELETE 쿼리문

destroy()
리턴값 : 이것도 affectedRows 를 리턴하는 듯한데, update랑은 다르게 []로 감싸져있지않다. 성공하면 1, 실패하면 0이나 기타를 리턴하는 듯.
아니면 이거는 true/false 의미로 1/0을 리턴하는 것일지도 모르겠다.

const comment = await Comment.destroy({
            where : {
                commentid : commentDto.commentid
                }
            }
        )

기타

increment() //기존 값을 지정한 숫자만큼 증가

참고한 사이트

마이그레이션 관련
https://crispypotato.tistory.com/156
https://any-ting.tistory.com/54

쿼리 관련
https://guiyomi.tistory.com/87
https://extbrain.tistory.com/47
https://includecoding.tistory.com/217

외래키 설정 관련
https://falsy.me/sequelize-2-%EC%BF%BC%EB%A6%AC-%EC%99%B8%EB%9E%98%ED%82%A4-for-mysql/
https://github.com/boostcamp-2020/IssueTracker-13/wiki/Sequelize-CLI-%26-Migration-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0
https://kyounghwan01.github.io/blog/etc/sequelize/sequelize-join/#include

profile
코딩 공부 ing..

0개의 댓글