zoukankan      html  css  js  c++  java
  • Sequelize-nodejs-6-Instances

    Instances实例

    Building a non-persistent instance构建非持久性实例

    In order to create instances of defined classes just do as follows. You might recognize the syntax if you coded Ruby in the past. Using the build-method will return an unsaved object, which you explicitly have to save.

    为了创建定义类的实例,可以像下面写的去做。在过去,如果你编写Ruby代码,你可能意识到他的语法。使用内置方法将返回没存储的对象,你需要显示存储:

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

    Built instances will automatically get default values when they were defined:

    构建实例将自动得到定义的默认值

    // 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,没有声明的值将设置为默认值

    To get it stored in the database, use the save-method and catch the events ... if needed:

    为了将其存储在数据库中,使用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
      })

    Creating persistent instances创建持久实例

    While an instance created with .build() requires an explicit .save() call to be stored in the database, .create() omits that requirement altogether and automatically stores your instance's data once called.

    上面肥持久实例的创建使用的是.build()并需要显示使用.save()进行存储。这里持久实例的创建使用的是.create(),一旦调用,将会自动存储你的实例数据

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

    It is also possible to define which attributes can be set via the create method. This can be especially very handy if you create database entries based on a form which can be filled by a user. Using that would for example allow you to restrict the User model to set only a username and an address but not an admin flag:

    通过create方法也可以定义能够被设置的属性。如果你基于一种被用户填满的形式来创建一个数据库条目,那么这将使其变得十分方便。例如,使用这个将允许你去限制User模型只被设置usernameaddress,而不设置admin标记

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

    从上面的结果可知,因为设置isAdmin为不能够被设置的属性,所以即使在创建的时候设置了这个属性,它的值也不会变化。

    Updating / Saving / Persisting an instance

    Now lets change some values and save changes to the database... There are two ways to do that:

    更改一些值并将变化保存到数据库,下面有两种方法:

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

    It's also possible to define which attributes should be saved when calling save, by passing an array of column names. This is useful when you set attributes based on a previously defined object. E.g. if you get the values of an object via a form of a web app. Furthermore this is used internally for update. This is how it looks like:

    在调用save的时候,是可以定义那些属性应该被存储的,通过传递列名数组。当你基于以前定义的对象设置属性时,它是十分有用的,例如,如果你是通过 web app的形式得到一个对象的值的时候。而且,这个将会被update内部使用:

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

    由结果可知,因为设置了description属性不能够被存储,所以在上面的例子中,其属性不变

    When you call save without changing any attribute, this method will execute nothing;

    当你调用save,但是没有改变任何属性时,将不会发生任何事情。

    Destroying / Deleting persistent instances

    Once you created an object and got a reference to it, you can delete it from the database. The relevant method is destroy:

    一旦你创建一个对象并得到其引用,你可以从数据库删掉它。相关的方法是-destroy:

    Task.create({ title: 'a task' }).then(task => {//task就是该对象的引用
      // now you see me...
      return task.destroy();//然后就能够通过引用调用destroy方法删除它
    }).then(() => {
     // now i'm gone :)
    })

    If the paranoid options is true, the object will not be deleted, instead the deletedAt column will be set to the current timestamp. To force the deletion, you can pass force: true to the destroy call:

    如果paranoid选项设置为true,对象将不能被删除,但是deletedAt列将会被设置成当前的时间戳。为了强制删除,你可以传递force: true给destroy调用:

    task.destroy({ force: true })

    Working in bulk (creating, updating and destroying multiple rows at once)一次执行多个

    In addition to updating a single instance, you can also create, update, and delete multiple instances at once. The functions you are looking for are called

    除了更新单个实例,你也可以一次create, update, and delete多个实例。下面的函数将被调用

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

    Since you are working with multiple models, the callbacks will not return DAO instances. BulkCreate will return an array of model instances/DAOs, they will however, unlike create, not have the resulting values of autoIncrement attributes. update and destroy will return the number of affected rows.

    当你执行的是多个模型,回调将不会返回DAO实例。BulkCreate酱返回模型实例/DAOs数组,不像create,没有自动增长属性的结果值。updatedestroy将返回被影响的行的数量。

    First lets look at bulkCreate

    首先是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
    })

    To update several rows at once:

    一次更新多行:

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

    And delete them:

    然后删除他们:

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

    If you are accepting values directly from the user, it might be beneficial to limit the columns that you want to actually insert.bulkCreate()accepts an options object as the second parameter. The object can have a fields parameter, (an array) to let it know which fields you want to build explicitly

    如果你从user中直接接受值,那么限制你真正想要插入的列是十分有用的。bulkCreate()接受选项对象作为第二个参数。对象能有fields参数,用于显式地了解你想要构建的域值:

    User.bulkCreate([
      { username: 'foo' },
      { username: 'bar', admin: true}//该数据将失败,因为admin不能设置
    ], { fields: ['username'] }).then(() => {
      // nope bar, you can't be admin!
    })

    bulkCreate was originally made to be a mainstream/fast way of inserting records, however, sometimes you want the luxury of being able to insert multiple rows at once without sacrificing model validations even when you explicitly tell Sequelize which columns to sift through. You can do by adding a validate: true property to the options object.

    一开始,bulkCreate被设置为主流/快速的方法去插入记录,可是有时你想要能够一次插入多行而不用牺牲模型的验证功能,甚至是当你显式地告诉Sequelize哪一列被选中。你可以通过添加validate: true属性到options对象中去实现:

    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长度大于range
      {code: '1234'},//失败,因为name不能为null
      {name: 'bar', code: '1'}
    ], { validate: true }).catch(errors => {
      /* console.log(errors) would look like:
      [
        { record:
        ...
        name: 'SequelizeBulkRecordError',
        message: 'Validation error',
        errors:
          { name: 'SequelizeValidationError',
            message: 'Validation error',
            errors: [Object] } },
        { record:
          ...
          name: 'SequelizeBulkRecordError',
          message: 'Validation error',
          errors:
            { name: 'SequelizeValidationError',
            message: 'Validation error',
            errors: [Object] } }
      ]
      */
    })

    Values of an instance

    If you log an instance you will notice, that there is a lot of additional stuff. In order to hide such stuff and reduce it to the very interesting information, you can use the get-attribute. Calling it with the option plain = true will only return the values of an instance.

    如果你记录实例的日志你就会注意到,这里有着一些额外的问题。为了隐藏这些问题并在非常有意思的信息中减少它的出现,你可以使用get-attribute。调用它并设置选项为plain = true,将会只返回实例的值:

    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
    // }

    Hint:You can also transform an instance into JSON by using JSON.stringify(instance). This will basically return the very same as values.

    提示:你也可以通过使用JSON.stringify(instance)将实例转成JSON格式。基本上是返回相同的值的。

    Reloading instances

    If you need to get your instance in sync, you can use the method reload. It will fetch the current data from the database and overwrite the attributes of the model on which the method has been called on.

    如果你想要同步得到你的实例,你可以使用方法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

    In order to increment values of an instance without running into concurrency issues, you may use increment.

    为了增加一个实例的值并不出现并发问题,你可以使用increment,下面有三种使用情况

    First of all you can define a field and the value you want to add to it.

    第一种,你可以定义一个值域以及你想要添加的值:

    User.findById(1).then(user => {
      return user.increment('my-integer-field', {by: 2})
    }).then(user => {
      // Postgres will return the updated user by default (unless disabled by setting { returning: false })
      // In other dialects, you'll want to call user.reload() to get the updated instance...
    })

    Second, you can define multiple fields and the value you want to add to them.

    第二种,定义多个值域和一个你想要添加给它们的值

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

    Third, you can define an object containing fields and its increment values.

    第三种,定义包含值域的对象及其对应的增量值

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

    Decrementing

    In order to decrement values of an instance without running into concurrency issues, you may use decrement.

    为了减少一个实例的值并不出现并发问题,你可以使用decrement,下面有三种使用情况

    First of all you can define a field and the value you want to add to it.

    第一种,你可以定义一个值域以及你想要添加的值:

    User.findById(1).then(user => {
      return user.decrement('my-integer-field', {by: 2})
    }).then(user => {
      // Postgres will return the updated user by default (unless disabled by setting { returning: false })
      // In other dialects, you'll want to call user.reload() to get the updated instance...
    })

    Second, you can define multiple fields and the value you want to add to them.

    第二种,定义多个值域和一个你想要添加给它们的值

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

    Third, you can define an object containing fields and its decrement values.

    第三种,定义包含值域的对象及其对应的增量值

    User.findById(1).then(user => {
      return user.decrement({
        'my-integer-field':    2,
        'my-very-other-field': 3
      })
    }).then(/* ... */)
  • 相关阅读:
    用orgmode写加密日记
    用emacs加密文件(使用ccrypt)
    C#使用注册表添加删除开机启动项
    WPF中使用第三方字体选择器
    使用rdesktop远程连接Windows桌面
    webbrowser 提交按钮没反应的问题解决办法
    C#中webBrowser加载页面中的不同域的iFrame的源代码的取得
    C# 天涯博客验证码识别(转)
    webbroser 清除COOKIES的解决办法
    使用C#实现ADSL自动拨号
  • 原文地址:https://www.cnblogs.com/wanghui-garcia/p/10064398.html
Copyright © 2011-2022 走看看