[Seqeulize 공식문서 번역하기] Model Instances

피누·2020년 3월 10일
0

원서와 친해지기

목록 보기
3/3
post-thumbnail

해당 자료는 seqeulize 5의 공식문서를 번역한 자료입니다.

Model Instances

Model instances는 DAO(Data Access Object)이다.
이번 가이드는 아래와 같은 setup을 가정으로 진행된다.

const { Sequelize, Model, DataTypes } = require("sequelize");
const sequelize = new Sequelize("sqlite::memory:");

const User = sequelize.define("user", {
  name: DataTypes.TEXT,
  favoriteColor: {
    type: DataTypes.TEXT,
    defaultValue: 'green'
  },
  age: DataTypes.INTEGER,
  cash: DataTypes.INTEGER
});

(async () => {
  await sequelize.sync({ force: true });
  // Code here
})();

Createing an instance

Model은 클래스임에도 new 키워드를 통해서 직접 인스턴스를 만들지 않는다. 대신 build 메소드를 사용한다.

const jane = User.build({ name: "Jane" });
console.log(jane instanceof User); // true
console.log(jane.name); // "Jane"

위 코드는 데이터베이스와 커뮤니케이션하지 않는다.(심지어 asynchronus조차 없다) build 메소드는 데이터베이스의 매핑된 데이터 오브젝트를 생성하는 역할만한다. 데이터베이스에 저장하기 위해서는 save 메소드를 사용한다.

await jane.save();
console.log('Jane was saved to the database!');

save 메소드 앞에 await 키워드가 있는 것에 주목하자. 즉 save 는 asynchronus(비동기) 메소드이다. 사실 Seqeulize의 대부분 method는 비동기이나 build는 예외 중 하나이다.

A very useful shortcut: the create method

Seqeulize는 buildsave 메소드를 결합한 create 메소드를 제공한다.

const jane = await User.create({ name: "Jane" });
// Jane exists in the database now!
console.log(jane instanceof User); // true
console.log(jane.name); // "Jane"

Note: logging instances

model instance를 logging하기 위해 바로 console.log를 사용하는 것은 Seqeulize instance가 가지는 많은 정보들을 출력한다. 대신에 .toJSON() 메소드를 이용해서 출력하는 것을 권장한다.
.toJSON() 메소드는 자동적으로 인스턴스에 JSON.stringify를 적용시켜준다.

const jane = await User.create({ name: "Jane" });
// console.log(jane); // Don't do this
console.log(jane.toJSON()); // This is good!
console.log(JSON.stringify(jane, null, 4)); // This is also good!
Default values

Defatult values

Build를 통해 생성한 인스턴스는 자동적으로 default values를 가진다.

const jane = User.build({ name: "Jane" });
console.log(jane.favoriteColor); // "green"

Updating an instance

save 함수를 다시 호출함으로서 인스턴스를 변경 할 수 있다.

const jane = await User.create({ name: "Jane" });
console.log(jane.name); // "Jane"
jane.name = "Ada";
// the name is still "Jane" in the database
await jane.save();
// Now the name was updated to "Ada" in the database!

Deleting an instance

destory 호출을 통해 인스턴스를 삭제 할 수 있다.

const jane = await User.create({ name: "Jane" });
console.log(jane.name); // "Jane"
await jane.destroy();
// Now this entry was removed from the database

Reloading an instance

reload 함수를 통해 데이터베이스로부터 인스턴스를 재로드 할 수 있다.

const jane = await User.create({ name: "Jane" });
console.log(jane.name); // "Jane"
jane.name = "Ada";
// the name is still "Jane" in the database
await jane.reload();
console.log(jane.name); // "Jane"

reload 함수는 데이터베이스의 최근 데이터를 가져오기 위한 SELECT 쿼리를 생성한다.

Saving only some fields

save 를 호출 할 때 column names array를 넘겨줌으로서 저장할 attributes 정의가 가능하다.

이것은 이전의 정의된 오브젝트의 속성을 설정 할 때 유용하다. 예를 들어 웹앱 형태를 통해 오브젝트의 value를 가져올 때이다. 게다가 이것은 내부적으로 update 구현체를 사용한다.

const jane = await User.create({ name: "Jane" });
console.log(jane.name); // "Jane"
console.log(jane.favoriteColor); // "green"
jane.name = "Jane II";
jane.favoriteColor = "blue";
await jane.save({ fields: ['name'] });
console.log(jane.name); // "Jane II"
console.log(jane.favoriteColor); // "blue"
// The above printed blue because the local object has it set to blue, but
// in the database it is still "green":
await jane.reload();
console.log(jane.name); // "Jane II"
console.log(jane.favoriteColor); // "green"

Change-awareness of save

save 메소드는 실제로 변한 필드에 대해서만 update가 일어나도록 내부적으로 최적화되어 있다. 아무것도 바꾸지 않은 상태에서 save를 호출하면, Sequelize는 save가 필요하지 않음을 알고 아무 동작도 하지 않는다. 즉 쿼리가 만들어지지 않는다. (단 여전히 Promise가 리턴되지만 곧바로 resolve 된다.)

또한 성능 향샹을 위해 save를 호출 할 때 변한 몇 개의 필드에 대해서만 UPDATE쿼리가 보내진다.

JPA의 save는 전체 필드 대상이다. 특정 필드만 update 하기위해서는 DynamicUpdate 어노테이션을 별도로 사용해야한다.

Incrementing and decrementing intger values

concurrency 이슈 없이 인스턴스 value의 증감을 위해서 Seqeulize는 incrementdecrement 메소드를 제공한다.

const jane = await User.create({ name: "Jane", age: 100 });
const incrementResult = await user.increment('age', { by: 2 });
// Note: to increment by 1 you can omit the `by` option and just do `user.increment('age')`

// In PostgreSQL, `incrementResult` will be the updated user, unless the option
// `{ returning: false }` was set (and then it will be undefined).

// In other dialects, `incrementResult` will be undefined. If you need the updated instance, you will have to call `user.reload()`.

increment, decrement는 다수의 필드에 대한 지원도 가능하다

const jane = await User.create({ name: "Jane", age: 100, cash: 5000 });
await jane.increment({
  'age': 2,
  'cash': 100
});

// If the values are incremented by the same amount, you can use this other syntax as well:
await jane.increment(['age', 'cash'], { by: 2 });
profile
어려운 문제를 함께 풀어가는 것을 좋아합니다.

0개의 댓글