Instances - 实例

    内置实例在定义时会自动获取默认值:

    1. // 首先定义模型
    2. const Task = sequelize.define('task', {
    3. title: Sequelize.STRING,
    4. rating: { type: Sequelize.STRING, defaultValue: 3 }
    5. })
    6. // 现在实例化一个对象
    7. const task = Task.build({title: 'very important task'})
    8. task.title // ==> 'very important task'
    9. task.rating // ==> 3

    要将其存储在数据库中,请使用 save 方法并捕获事件(如果需要):

    1. project.save().then(() => {
    2. // 回调
    3. })
    4. task.save().catch(error => {
    5. // 呃
    6. })
    7. // 还可以使用链式构建来保存和访问对象:
    8. Task
    9. .build({ title: 'foo', description: 'bar', deadline: new Date() })
    10. .save()
    11. .then(anotherTask => {
    12. // 您现在可以使用变量 anotherTask 访问当前保存的任务
    13. })
    14. .catch(error => {
    15. // Ooops,做一些错误处理
    16. })

    创建持久性实例

    虽然使用 .build() 创建的实例需要显式的 .save() 调用来存储到 database&comma 中;
    .create() 完全省略了这个要求,一旦调用就自动存储实例的数据。

    1. Task.create({ title: 'foo', description: 'bar', deadline: new Date() }).then(task => {
    2. // 你现在可以通过变量 task 来访问新创建的 task
    3. })

    也可以通过 create 方法定义哪些属性可以设置。 如果你创建基于可由用户填写的表单的数据库条目,这将非常方便。 例如,使用这种方式,你可以限制 User 模型,仅设置 username 和 address,而不是 admin 标志:

    1. User.create({ username: 'barfooz', isAdmin: true }, { fields: [ 'username' ] }).then(user => {
    2. // 我们假设 isAdmin 的默认值为 false:
    3. console.log(user.get({
    4. plain: true
    5. })) // => { username: 'barfooz', isAdmin: false }
    6. })

    更新 / 保存 / 持久化一个实例

    现在可以更改一些值并将更改保存到数据库…有两种方法可以实现:

    1. // 方法 1
    2. task.title = 'a very different title now'
    3. task.save().then(() => {})
    4. // 方法 2
    5. task.update({
    6. title: 'a very different title now'
    7. }).then(() => {})

    通过传递列名数组,调用 save 时也可以定义哪些属性应该被保存。 当您基于先前定义的对象设置属性时,这是有用的。 例如。 如果您通过Web应用程序的形式获取对象的值。 此外,这在 update 内部使用。 它就像这样:

    1. task.title = 'foooo'
    2. task.description = 'baaaaaar'
    3. task.save({fields: ['title']}).then(() => {
    4. // title 现在将是 “foooo”,而 description 与以前一样
    5. })
    6. // 使用等效的 update 调用如下所示:
    7. task.update({ title: 'foooo', description: 'baaaaaar'}, {fields: ['title']}).then(() => {
    8. // title 现在将是 “foooo”,而 description 与以前一样

    当你调用 save而不改变任何属性的时候,这个方法什么都不执行。

    创建对象并获得对象的引用后,可以从数据库中删除它。 相关的方法是 destroy

    1. task.destroy({ force: true })

    批量操作(一次创建,更新和销毁多行)

    除了更新单个实例之外,你还可以一次创建,更新和删除多个实例。 调用你需要的方法

    • Model.update
    • Model.destroy

    由于你使用多个模型,回调将不会返回DAO实例。 BulkCreate将返回一个模型实例/DAO的数组,但是它们不同于create,没有 autoIncrement 属性的结果值. updatedestroy 将返回受影响的行数。

    首先看下 bulkCreate

    1. User.bulkCreate([
    2. { username: 'barfooz', isAdmin: true },
    3. { username: 'foo', isAdmin: true },
    4. { username: 'bar', isAdmin: false }
    5. ]).then(() => { // 注意: 这里没有凭据, 然而现在你需要...
    6. return User.findAll();
    7. }).then(users => {
    8. console.log(users) // ... 以获取 user 对象的数组
    9. })

    一次更新几行:

    1. Task.bulkCreate([
    2. {subject: 'programming', status: 'executing'},
    3. {subject: 'reading', status: 'executing'},
    4. {subject: 'programming', status: 'finished'}
    5. ]).then(() => {
    6. return Task.update(
    7. { status: 'inactive' }, /* 设置属性的值 */
    8. { where: { subject: 'programming' }} /* where 规则 */
    9. );
    10. }).spread((affectedCount, affectedRows) => {
    11. // .update 在数组中返回两个值,因此我们使用 .spread
    12. // 请注意,affectedRows 只支持以 returning: true 的方式进行定义
    13. // affectedCount 将会是 2
    14. return Task.findAll();
    15. }).then(tasks => {
    16. console.log(tasks) // “programming” 任务都将处于 “inactive” 状态
    17. })

    然后删除它们:

    1. Task.bulkCreate([
    2. {subject: 'programming', status: 'executing'},
    3. {subject: 'reading', status: 'executing'},
    4. {subject: 'programming', status: 'finished'}
    5. ]).then(() => {
    6. return Task.destroy({
    7. where: {
    8. subject: 'programming'
    9. },
    10. truncate: true /* 这将忽 where 并用 truncate table 替代 */
    11. });
    12. }).then(affectedRows => {
    13. // affectedRows 将会是 2
    14. return Task.findAll();
    15. }).then(tasks => {
    16. console.log(tasks) // 显示 tasks 内容
    17. })

    如果您直接从 user 接受值,则限制要实际插入的列可能会更好。bulkCreate() 接受一个选项对象作为第二个参数。 该对象可以有一个 fields 参数(一个数组),让它知道你想要明确构建哪些字段

    1. User.bulkCreate([
    2. { username: 'foo' },
    3. { username: 'bar', admin: true}
    4. ], { fields: ['username'] }).then(() => {
    5. // admin 将不会被构建
    6. })

    bulkCreate 最初是成为 主流/快速 插入记录的方法,但是有时您希望能够同时插入多行而不牺牲模型验证,即使您明确地告诉 Sequelize 去筛选哪些列。 你可以通过在options对象中添加一个 validate: true 属性来实现。

    1. const Tasks = sequelize.define('task', {
    2. name: {
    3. type: Sequelize.STRING,
    4. validate: {
    5. notNull: { args: true, msg: 'name cannot be null' }
    6. }
    7. },
    8. code: {
    9. type: Sequelize.STRING,
    10. validate: {
    11. }
    12. })
    13. Tasks.bulkCreate([
    14. {name: 'foo', code: '123'},
    15. {code: '1234'},
    16. {name: 'bar', code: '1'}
    17. ], { validate: true }).catch(errors => {
    18. /* console.log(errors) 看起来像这样:
    19. [
    20. { record:
    21. ...
    22. name: 'SequelizeBulkRecordError',
    23. message: 'Validation error',
    24. errors:
    25. { name: 'SequelizeValidationError',
    26. message: 'Validation error',
    27. errors: [Object] } },
    28. { record:
    29. ...
    30. name: 'SequelizeBulkRecordError',
    31. message: 'Validation error',
    32. errors:
    33. { name: 'SequelizeValidationError',
    34. message: 'Validation error',
    35. errors: [Object] } }
    36. ]
    37. */
    38. })

    一个实例的值

    如果你记录一个实例,你会注意到有很多额外的东西。 为了隐藏这些东西并将其减少到非常有趣的信息,您可以使用 get 属性。 使用选项 plain: true 调用它将只返回一个实例的值。

    如果你需要让你的实例同步,你可以使用 reload 方法。 它将从数据库中获取当前数据,并覆盖调用该方法的模型的属性。

    1. Person.findOne({ where: { name: 'john' } }).then(person => {
    2. person.name = 'jane'
    3. console.log(person.name) // 'jane'
    4. person.reload().then(() => {
    5. console.log(person.name) // 'john'
    6. })
    7. })

    递增

    为了增加实例的值而不发生并发问题,您可以使用 increment

    首先,你可以定义一个字段和要添加的值。

    1. User.findById(1).then(user => {
    2. return user.increment('my-integer-field', {by: 2})
    3. }).then(user => {
    4. // Postgres默认会返回更新的 user (除非通过设置禁用 { returning: false })
    5. // 在其他方言中,您将需要调用 user.reload() 来获取更新的实例...
    6. })

    然后,你可以定义多个字段和要添加到其中的值。

    1. User.findById(1).then(user => {
    2. return user.increment([ 'my-integer-field', 'my-very-other-field' ], {by: 2})
    3. }).then(/* ... */)

    最后,你可以定义一个包含字段及其递增值的对象。

    1. User.findById(1).then(user => {
    2. return user.increment({
    3. 'my-integer-field': 2,
    4. 'my-very-other-field': 3
    5. })
    6. }).then(/* ... */)

    递减

    为了减少一个实例的值而不遇到并发问题,你可以使用 decrement

    首先,你可以定义一个字段和要添加的值。

    1. User.findById(1).then(user => {
    2. return user.decrement('my-integer-field', {by: 2})
    3. }).then(user => {
    4. // Postgres默认会返回更新的 user (除非通过设置禁用 { returning: false })
    5. // 在其他方言中,您将需要调用 user.reload() 来获取更新的实例...
    6. })

    然后,你可以定义多个字段和要添加到其中的值。

    1. User.findById(1).then(user => {
    2. return user.decrement([ 'my-integer-field', 'my-very-other-field' ], {by: 2})
    3. }).then(/* ... */)