モデルインスタンス
ご存知のとおり、モデルはES6クラスです。クラスのインスタンスは、そのモデルからの1つのオブジェクト(データベース内のテーブルの1つの行にマッピングされる)を表します。このように、モデルインスタンスはDAOです。
このガイドでは、以下の設定を前提としています
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
})();
インスタンスの作成
モデルはクラスですが、`new`演算子を使用して直接インスタンスを作成しないでください。代わりに、`build`メソッドを使用する必要があります
const jane = User.build({ name: 'Jane' });
console.log(jane instanceof User); // true
console.log(jane.name); // "Jane"
ただし、上記のコードはデータベースとまったく通信しません(非同期でもないことに注意してください)!これは、`build`メソッドは、データベースにマッピング*できる* データを*表す*オブジェクトを作成するだけだからです。このインスタンスをデータベースに実際に保存(つまり永続化)するには、`save`メソッドを使用する必要があります
await jane.save();
console.log('Jane was saved to the database!');
上記のコードスニペットで`await`を使用していることからわかるように、`save`は非同期メソッドです。実際、ほとんどすべてのSequelizeメソッドは非同期です。`build`はごく少数の例外の1つです。
非常に便利なショートカット:`create`メソッド
Sequelizeは、上記の`build`メソッドと`save`メソッドを1つのメソッドにまとめた`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"
注:インスタンスのログ出力
Sequelizeインスタンスには多くのものがアタッチされているため、モデルインスタンスを直接`console.log`に出力しようとすると、多くの不要な情報が出力されます。代わりに、`.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!
デフォルト値
構築されたインスタンスは自動的にデフォルト値を取得します
const jane = User.build({ name: 'Jane' });
console.log(jane.favoriteColor); // "green"
インスタンスの更新
インスタンスのフィールドの値を変更した場合、`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!
`set`メソッドを使用して、複数のフィールドを一度に更新できます
const jane = await User.create({ name: 'Jane' });
jane.set({
name: 'Ada',
favoriteColor: 'blue',
});
// As above, the database still has "Jane" and "green"
await jane.save();
// The database now has "Ada" and "blue" for name and favorite color
ここでの`save()`は、前の`set`呼び出しでの変更だけでなく、このインスタンスに加えられた他の変更も永続化することに注意してください。特定のフィールドセットを更新する場合は、`update`を使用できます
const jane = await User.create({ name: 'Jane' });
jane.favoriteColor = 'blue';
await jane.update({ name: 'Ada' });
// The database now has "Ada" for name, but still has the default "green" for favorite color
await jane.save();
// Now the database has "Ada" for name and "blue" for favorite color
インスタンスの削除
`destroy`を呼び出すことで、インスタンスを削除できます
const jane = await User.create({ name: 'Jane' });
console.log(jane.name); // "Jane"
await jane.destroy();
// Now this entry was removed from the database
インスタンスの再読み込み
`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"
再読み込み呼び出しは、データベースから最新のデータを取得するための`SELECT`クエリを生成します。
一部のフィールドのみの保存
列名の配列を渡すことにより、`save`を呼び出すときに保存する属性を定義できます。
これは、以前に定義されたオブジェクトに基づいて属性を設定する場合、たとえば、Webアプリのフォームを介してオブジェクトの値を取得する場合に役立ちます。さらに、これは`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"
`save`の変更認識
`save`メソッドは、実際に変更されたフィールドのみを更新するように内部的に最適化されています。つまり、何も変更せずに`save`を呼び出すと、Sequelizeは保存が不要であることを認識し、何もしません。つまり、クエリは生成されません(Promiseは返されますが、すぐに解決されます)。
また、`save`を呼び出すときに少数の属性のみが変更された場合、パフォーマンスを向上させるために、それらのフィールドのみが`UPDATE`クエリで送信されます。
整数値の増減
同時実行の問題に陥ることなくインスタンスの値を増減するために、Sequelizeは`increment`および`decrement`インスタンスメソッドを提供します。
const jane = await User.create({ name: 'Jane', age: 100 });
const incrementResult = await jane.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()`.
複数のフィールドを一度に増やすこともできます
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 });
減算もまったく同じように機能します。