final 프로젝트 중에, 유저가 보스몬스터를 잡았을 경우에 몬스터를 잡기위해 참가한 모든 유저에게 보상을 지급하는 내용이 있었습니다.
작성하는 중에, 고민되던 건 어떻게하면 이걸 간결하게 할 수 있을까 였습니다.
처음에 생각한 방법은 findAll로 배열을 받아와서 forEach로 각각의 요소마다 update를 해서 데이터를 업데이트하는 것이였습니다.
그러다보니 findAll, update라는 두번의 과정을 거쳐야하는데 한번에 하는게 없을까? 싶어 찾아보게되었습니다.
bulkCreate는 다수의 인스턴스를 생성하기 위해있는 메서드입니다.
User.bulkCreate([
{ username: 'barfooz', isAdmin: true },
{ username: 'foo', isAdmin: true },
{ username: 'bar', isAdmin: false }
])
.then(() => {
return User.update({
{ isAdmin : true}, // isAdmin값을 true로
{ where : {username : 'foo' }} // username 이 foo인 isAdmin값을 true로 바꿉니다 전부
})
})
이 방법 말고도 updateOnDuplicate 옵션을 이용할 수도 있습니다.
User.bulkCreate({
[ isAdmin : true],
{updateOnDuplicate : ['username']} //primaryKey값의 key값
})
updateOnDuplicate는 배열안에 있는 키값이 테이블에서 중복되지않으면 create를 실행하고 중복되면 해당 키값의 내용을 update실행합니다.
그리고 배열의 값을 반환합니다.
여러항목 삭제 역시도 있습니다.
이렇게 실컷찾아보고는...프로젝트에 적용할때는 월래할려고했던 방식 그대로 했습니다.
계속 안되길래 로그 찍어보다가 찾게 돼서 저처럼 헤매는 분들이 많지 않았으면 하는 바램으로 댓글 남깁니다.
updateOnDuplicate 배열 안엔 primaryKey 가 아니라, 중복됐을 경우 업데이트 할 column 들을 넣어줘야 합니다.
실제로 이 코드는 SQL 문에서 'ON DUPLICATE KEY UPDATE' 로 실행이 되고,
이는 Primary Key 또는 Unique 제약이 걸렸을 경우 중복에 걸린 row 에 대해 업데이트 할 column 들을 지정해주는 SQL 입니다.
이 블로그가 관련 키워드 검색 시 최상단에 노출되기 때문에 많은 사람들이 삽질하지 않을 수 있도록 원글 수정해주신다면 좋을 것 같습니다.