Sequelizejs中的.save和.create有什么区别?

15

我是Sequelize的新手,正在努力理解这个全新的ORM世界是如何工作的。有一件事情我似乎无法理解,那就是在Sequelizejs中“.create”和“.save”的区别。我已经使用两种方法编写了测试函数,除了略微不同的语法外,它们似乎都做着完全相同的事情。

这是使用“.save”方法的示例

 models.User.build({
    username: req.body.username,
    password: req.body.password,
    first_name: req.body.firstName,
    last_name: req.body.lastName
  })
  .save()
  .then(function(task){
    // some function...
  })
  .catch(function(error){
    // some function...
  });

这是使用“.create”方法

  models.User.create({
    username: req.body.username,
    password: req.body.password,
    first_name: req.body.firstName,
    last_name: req.body.lastName
  }).then(function(data) {
    // some function...
  });

我在这里没有看到什么?


1
使用create方法时,您无需调用.save()方法 :) - Molda
2个回答

20

如文档所述 http://docs.sequelizejs.com/en/latest/docs/instances/

方法.build()创建一个非持久化实例,这意味着数据尚未保存在数据库中,而仅存储在内存中,在执行期间。当程序停止(服务器崩溃,执行结束或类似情况)时,使用.build()创建的实例将丢失。

这就是.save()发挥作用的地方。它将由.build()方法构建的实例的数据存储在数据库中。

这种方法允许您在将其存储在数据库之前以所需的方式操作实例。

.create()方法只需在同一命令中.build().save()一个实例。这是在简单情况下没有必要操作实例的方便方式,让您通过单个命令将数据存储在数据库中。 例如:

这个:

User.build({ name: "John" }).save().then(function(newUser){
    console.log(newUser.name); // John
    // John is now in your db!
}).catch(function(error){
    // error
});

与此相同:

User.create({ name: "John"}).then(function(newUser){
    console.log(newUser.name); // John
    // John is now in your db!
}).catch(function(error){
    // error
});

但是你可以做类似这样的事情:

var user = User.build({ name: "John"}); // nothing in your db yet

user.name = "Doe"; // still, nothing on your db

user.save().then(function(newUser){
    console.log(newUser.name); // Doe
    // Doe is now in your db!
}).catch(function(error){
    // error
});

基本上,.build().save() 让您有能力在将数据存储到数据库之前修改实例。


1
显然,当 isNewRecord 被设置为 false 时, build().save() 将进行更新操作,但是 create() 不会进行更新操作,无论 isNewRecord 的值如何。(使用 Sequelize v3) - steampowered
当您使用 build 时,对象将具有模型中定义的默认值。 - Hardik Sondagar

3
当以这种方式使用时,它们的意思相同。.create() 在内部是 .build().save()
但在你的第一个例子中,最重要的是,.build() 实例化了 ActiveRecord,获得了诸如关联方法和所有 getter 和 setter 方法等方法。而 .create() 方法仅在创建完成后才返回 ActiveRecord。
假设你的用户与一个 picture 相关联。有时你会使用 build 方法来实现:
var user = models.User.build({
    userName: req.body.userName
})

// start doing things with the user instance

user.hasPictures().then(function(hasPictures) {
    // does user have pictures?
    console.log(hasPictures)

})

更重要的是,setter方法可能对你更有兴趣。请参见https://sequelize.org/docs/v6/core-concepts/getters-setters-virtuals/ 假设您可能拥有一个setter方法,它会执行以下操作:
const User = sequelize.define('user', {
  username: DataTypes.STRING,
  nationality: DataTypes.STRING,
  name: {
    type: DataTypes.STRING,
    set([firstName, lastName]) {

      if (this.nationality === 'Chinese' || this.nationality === 'Korean' ) {
        return this.setDataValue('name', `${lastName} ${firstName}`)
      }

      // for all other nationalities, we default to having the first name in front.
      this.setDataValue('name', `${firstName} ${lastName}`)
    }
  }
})

现在你可以使用你的user ActiveRecord进行以下操作:

const user = User.build({ userName: 'parkJS' })
user.nationality = 'Korean'
user.setDataValue('name', ['Ji Sung', 'Park'])
console.log(user.name) // outputs 'Park Ji Sung'

const user2 = User.build({ userName: 'davidb' })
user2.nationality = 'British'
user2.setDataValue('name', ['David', 'Beckham'])
console.log(user2.name) // outputs 'David Beckham'

// call any other setter methods here to complete the model.

// then finally call .save()
user.save()
user2.save()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接