Sequelize 中文文檔 v4 - Instances - 實例

Instances - 實例

此係列文章的應用示例已發佈於 GitHub: sequelize-docs-Zh-CN. 能夠 Fork 幫助改進或 Star 關注更新. 歡迎 Star.git

構建非持久性實例

爲了建立定義類的實例,請執行如下操做。 若是你之前編寫過 Ruby,你可能認識該語法。 使用 build - 該方法將返回一個未保存的對象,你要明確地保存它。github

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()
})

內置實例在定義時會自動獲取默認值:數據庫

// 首先定義模型
const Task = sequelize.define('task', {
  title: Sequelize.STRING,
  rating: { type: Sequelize.STRING, defaultValue: 3 }
})
 
// 如今實例化一個對象
const task = Task.build({title: 'very important task'})
 
task.title  // ==> 'very important task'
task.rating // ==> 3

要將其存儲在數據庫中,請使用 save 方法並捕獲事件(若是須要):數組

project.save().then(() => {
  // 回調
})
 
task.save().catch(error => {
  // 呃
})
 
// 還可使用鏈式構建來保存和訪問對象:
Task
  .build({ title: 'foo', description: 'bar', deadline: new Date() })
  .save()
  .then(anotherTask => {
    // 您如今可使用變量 anotherTask 訪問當前保存的任務
  })
  .catch(error => {
    // Ooops,作一些錯誤處理
  })

建立持久性實例

除了構建對象以外,還須要一個明確的保存調用來存儲在數據庫中,能夠經過一個命令執行全部這些步驟。 它被稱爲 create併發

Task.create({ title: 'foo', description: 'bar', deadline: new Date() }).then(task => {
  // 你如今能夠經過變量 task 來訪問新建立的 task
})

也能夠經過 create 方法定義哪些屬性能夠設置。 若是你建立基於可由用戶填寫的表單的數據庫條目,這將很是方便。 例如,使用這種方式,你能夠限制 User 模型,僅設置 username 和 address,而不是 admin 標誌:ide

User.create({ username: 'barfooz', isAdmin: true }, { fields: [ 'username' ] }).then(user => {
  // 咱們假設 isAdmin 的默認值爲 false:
  console.log(user.get({
    plain: true
  })) // => { username: 'barfooz', isAdmin: false }
})

更新 / 保存 / 持久化一個實例

如今能夠更改一些值並將更改保存到數據庫...有兩種方法能夠實現:oop

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

經過傳遞列名數組,調用 save 時也能夠定義哪些屬性應該被保存。 當您基於先前定義的對象設置屬性時,這是有用的。 例如。 若是您經過Web應用程序的形式獲取對象的值。 此外,這在 update 內部使用。 它就像這樣:ui

task.title = 'foooo'
task.description = 'baaaaaar'
task.save({fields: ['title']}).then(() => {
 // title 如今將是 「foooo」,而 description 與之前同樣
})
 
// 使用等效的 update 調用以下所示:
task.update({ title: 'foooo', description: 'baaaaaar'}, {fields: ['title']}).then(() => {
 //  title 如今將是 「foooo」,而 description 與之前同樣
})

當你調用 save 而不改變任何屬性的時候,這個方法什麼都不執行。this

銷燬 / 刪除持久性實例

建立對象並得到對象的引用後,能夠從數據庫中刪除它。 相關的方法是 destroyidea

Task.create({ title: 'a task' }).then(task => {
  // 獲取到 task 對象...
  return task.destroy();
}).then(() => {
 // task 對象已被銷燬
})

若是 paranoid 選項爲 true,則不會刪除該對象,而將 deletedAt 列設置爲當前時間戳。 要強制刪除,能夠將 force: true 傳遞給 destroy 調用:

task.destroy({ force: true })

批量操做(一次建立,更新和銷燬多行)

除了更新單個實例以外,你還能夠一次建立,更新和刪除多個實例。 調用你須要的方法

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

因爲你使用多個模型,回調將不會返回DAO實例。 BulkCreate將返回一個模型實例/DAO的數組,可是它們不一樣於create,沒有 autoIncrement 屬性的結果值. updatedestroy 將返回受影響的行數。

首先看下 bulkCreate

User.bulkCreate([
  { username: 'barfooz', isAdmin: true },
  { username: 'foo', isAdmin: true },
  { username: 'bar', isAdmin: false }
]).then(() => { // 注意: 這裏沒有憑據, 然而如今你須要...
  return User.findAll();
}).then(users => {
  console.log(users) // ... 以獲取 user 對象的數組
})

一次更新幾行:

Task.bulkCreate([
  {subject: 'programming', status: 'executing'},
  {subject: 'reading', status: 'executing'},
  {subject: 'programming', status: 'finished'}
]).then(() => {
  return Task.update(
    { status: 'inactive' }, /* 設置屬性的值 */,
    { where: { subject: 'programming' }} /* where 規則 */
  );
}).spread((affectedCount, affectedRows) => {
  // .update 在數組中返回兩個值,所以咱們使用 .spread
  // 請注意,affectedRows 只支持以 returning: true 的方式進行定義
  
  // affectedCount 將會是 2
  return Task.findAll();
}).then(tasks => {
  console.log(tasks) // 「programming」 任務都將處於 「inactive」 狀態
})

而後刪除它們:

Task.bulkCreate([
  {subject: 'programming', status: 'executing'},
  {subject: 'reading', status: 'executing'},
  {subject: 'programming', status: 'finished'}
]).then(() => {
  return Task.destroy({
    where: {
      subject: 'programming'
    },
    truncate: true /* 這將忽 where 並用 truncate table 替代  */
  });
}).then(affectedRows => {
  // affectedRows 將會是 2
  return Task.findAll();
}).then(tasks => {
  console.log(tasks) // 顯示 tasks 內容
})

若是您直接從 user 接受值,則限制要實際插入的列可能會更好。bulkCreate() 接受一個選項對象做爲第二個參數。 該對象能夠有一個 fields 參數(一個數組),讓它知道你想要明確構建哪些字段

User.bulkCreate([
  { username: 'foo' },
  { username: 'bar', admin: true}
], { fields: ['username'] }).then(() => {
  // admin 將不會被構建
})

bulkCreate 最初是成爲 主流/快速 插入記錄的方法,可是有時您但願可以同時插入多行而不犧牲模型驗證,即便您明確地告訴 Sequelize 去篩選哪些列。 你能夠經過在options對象中添加一個 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) 看起來像這樣:
  [
    { record:
    ...
    errors:
      { name: 'SequelizeValidationError',
        message: 'Validation error',
        errors: [Object] } },
    { record:
      ...
      errors:
        { name: 'SequelizeValidationError',
        message: 'Validation error',
        errors: [Object] } }
  ]
  */
  
})

一個實例的值

若是你記錄一個實例,你會注意到有不少額外的東西。 爲了隱藏這些東西並將其減小到很是有趣的信息,您可使用 get 屬性。 使用選項 plain: true 調用它將只返回一個實例的值。

Person.create({
  name: 'Rambow',
  firstname: 'John'
}).then(john => {
  console.log(john.get({
    plain: true
  }))
})
 
// 結果:
 
// { 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。 基本上與 values 返回的相同。

重載實例

若是你須要讓你的實例同步,你可使用 reload 方法。 它將從數據庫中獲取當前數據,並覆蓋調用該方法的模型的屬性。

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

遞增

爲了增長實例的值而不發生併發問題,您可使用 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(/* ... */)

遞減

爲了減小一個實例的值而不遇到併發問題,你可使用 decrement

首先,你能夠定義一個字段和要添加的值。

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(/* ... */)

若是這篇文章對您有幫助, 感謝 下方點贊 或 Star GitHub: sequelize-docs-Zh-CN 支持, 謝謝.

相關文章
相關標籤/搜索