实例

构建非持久性实例

如果你仅仅只是要创建一个已定义了的模型的非持久性实例,如用下面的方法即可,build 方法将返回一个未持久化的实例:

const project = Project.build({
  title: 'my awesome project',
  description: 'woot woot. this will make me a rich man'
})

const task = Task.build({
  title: 'specify the project idea',
  description: 'bla',
  deadline: new Date()
})

如果定义了默认值,在 build 时又未指定值,那么 build 之后的实例将自动获取默认值:

// first define the model
const Task = sequelize.define('task', {
  title: Sequelize.STRING,
  rating: { type: Sequelize.STRING, defaultValue: 3 }
})

// now instantiate an object
const task = Task.build({title: 'very important task'})

task.title  // ==> 'very important task'
task.rating // ==> 3

如果要将一个非持久化的实例保存至数据库,直接使用 save 方法即可,适当的时候,还需要捕获它的相关事件:

project.save().then(() => {
  // my nice callback stuff
})

task.save().catch(error => {
  // mhhh, wth!
})

// you can also build, save and access the object with chaining:
Task
  .build({ title: 'foo', description: 'bar', deadline: new Date() })
  .save()
  .then(anotherTask => {
    // you can now access the currently saved task with the variable anotherTask... nice!
  })
  .catch(error => {
    // Ooops, do some error-handling
  })

创建持久化的实例

如果你想创建一个持久化至数据库中的实例的话,可以使用 create 方法即可:

Task.create({ title: 'foo', description: 'bar', deadline: new Date() }).then(task => {
  // you can now access the newly created task via the variable task
})

你还可以设定哪些字段是可以在创建的过程中被指定的:

User.create({ username: 'barfooz', isAdmin: true }, { fields: [ 'username' ] }).then(user => {
  // let's assume the default of isAdmin is false:
  console.log(user.get({
    plain: true
  })) // => { username: 'barfooz', isAdmin: false }
})

更新、保存以及持久化更新一个实例

现在我们来看看如何更新一个已持久化的实例,并将修改同步至数据库中:

// way 1
task.title = 'a very different title now'
task.save().then(() => {})

// way 2
task.update({
  title: 'a very different title now'
}).then(() => {})

create 一样,你同样还可以指定哪些字段是可以被更新的:

task.title = 'foooo'
task.description = 'baaaaaar'
task.save({fields: ['title']}).then(() => {
 // title will now be 'foooo' but description is the very same as before
})

// The equivalent call using update looks like this:
task.update({ title: 'foooo', description: 'baaaaaar'}, {fields: ['title']}).then(() => {
 // title will now be 'foooo' but description is the very same as before
})

销毁、删除已持久化的实例

当你创建了一个实例,并得到该实例的引用之后,即可使用 destroy 方法销毁该实例:

Task.create({ title: 'a task' }).then(task => {
  // now you see me...
  return task.destroy();
}).then(() => {
 // now i'm gone :)
})

如果 paranoid 选项被设置为 true,该对象将不会被删除,而是会被添加一个 deletedAt 字段,用于表示该条记录何时被删除,如果要强制删除,可以在删除的方法中传递参数 forcetrue

task.destroy({ force: true })

指操作(创建、更新、销毁多条记录)

额外的,Sequelize还提供了让你可以进行指操作的方法,它们分别是:

  • Model.bulkCreate
  • Model.update
  • Model.destroy

当你对多条记录进行批量操作时,返回的将不再是一个DAO对象,对于 Model.bulkCreate 将会返回所有被成功创建的实例的集合(数组),但不同于 create 创建的实例,自增类型的字段将没有值, updatedestroy 将会返回所有受影响的记录数量。

先让我们看看 Model.bulkCreate

User.bulkCreate([
  { username: 'barfooz', isAdmin: true },
  { username: 'foo', isAdmin: true },
  { username: 'bar', isAdmin: false }
]).then(() => { // Notice: There are no arguments here, as of right now you'll have to...
  return User.findAll();
}).then(users => {
  console.log(users) // ... in order to get the array of user objects
})

要批量更新多条记录:

Task.bulkCreate([
  {subject: 'programming', status: 'executing'},
  {subject: 'reading', status: 'executing'},
  {subject: 'programming', status: 'finished'}
]).then(() => {
  return Task.update(
    { status: 'inactive' }, /* set attributes' value */,
    { where: { subject: 'programming' }} /* where criteria */
  );
}).spread((affectedCount, affectedRows) => {
  // .update returns two values in an array, therefore we use .spread
  // Notice that affectedRows will only be defined in dialects which support returning: true

  // affectedCount will be 2
  return Task.findAll();
}).then(tasks => {
  console.log(tasks) // the 'programming' tasks will both have a status of 'inactive'
})

接着删除他们:

Task.bulkCreate([
  {subject: 'programming', status: 'executing'},
  {subject: 'reading', status: 'executing'},
  {subject: 'programming', status: 'finished'}
]).then(() => {
  return Task.destroy({
    where: {
      subject: 'programming'
    },
    truncate: true /* this will ignore where and truncate the table instead */
  });
}).then(affectedRows => {
  // affectedRows will be 2
  return Task.findAll();
}).then(tasks => {
  console.log(tasks) // no programming, just reading :(
})

如果你是从其它数据源接收数据,那么,限制被更新的值的字段类型是很有必要的,与 create 一样,你可以在 bulkCreate 的第二个参数中传递一个对象作为参数,该对象中的 fields 值即可表示哪些字段是可以被创建的:

User.bulkCreate([
  { username: 'foo' },
  { username: 'bar', admin: true}
], { fields: ['username'] }).then(() => {
  // nope bar, you can't be admin!
})

bulkCreate 使用的是主流/快速的方法进行多记录的插入,但是有时候你还是希望对模型中的数据进行验证,此时,你同样可以使用 validate: true

const Tasks = sequelize.define('task', {
  name: {
    type: Sequelize.STRING,
    validate: {
      notNull: { args: true, msg: 'name cannot be null' }
    }
  },
  code: {
    type: Sequelize.STRING,
    validate: {
      len: [3, 10]
    }
  }
})

Tasks.bulkCreate([
  {name: 'foo', code: '123'},
  {code: '1234'},
  {name: 'bar', code: '1'}
], { validate: true }).catch(errors => {
  /* console.log(errors) would look like:
  [
    { record:
    ...
    errors:
      { name: 'SequelizeValidationError',
        message: 'Validation error',
        errors: [Object] } },
    { record:
      ...
      errors:
        { name: 'SequelizeValidationError',
        message: 'Validation error',
        errors: [Object] } }
  ]
  */
})

实例的值

如果你打印出一个实例,你会发现很多额外的信息,如果你只想得到一个纯净的实例对象,那么可以使用使用的 get 方法:

Person.create({
  name: 'Rambow',
  firstname: 'John'
}).then(john => {
  console.log(john.get({
    plain: true
  }))
})

// result:

// { name: 'Rambow',
//   firstname: 'John',
//   id: 1,
//   createdAt: Tue, 01 May 2012 19:12:16 GMT,
//   updatedAt: Tue, 01 May 2012 19:12:16 GMT
// }

小技巧:你还可以使用 JSON.stringify(instance) 得到实例JSON化后的字符串,它也是一个纯净的对象的表示。

重载实例

如果你想从数据库中重载实例,可以使用实例的 reload 方法:

Person.findOne({ where: { name: 'john' } }).then(person => {
  person.name = 'jane'
  console.log(person.name) // 'jane'

  person.reload().then(() => {
    console.log(person.name) // 'john'
  })
})

Incrementing

如果你想在增加某一个值,而避免并发问题,可以使用 increment 方法:

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

你还可以一次性定义多个字段:

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

当然,你还可以定义每一个字段要增加的值:

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

Decrementing

与 Incrementing 一样:

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

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

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

results matching ""

    No results matching ""