zoukankan      html  css  js  c++  java
  • 一个关于vue+mysql+express的全栈项目(四)------ sequelize中部分解释

    一、模型的引入

    引入db.js
    const sequelize = require('./db')
    sequelize本身就是一个对象,他提供了众多的方法,
    const account = sequelize.model('account') //获取account这个模型

    二,数据库基本操作(增、删、改、查)

    增:

    account.create(data).then(doc => {
        const {user_name, user_id, user_info, avatar} = doc
        res.cookie('user_id', user_id)
        return res.json({
          code: 0,
          data: {
            user_name: user_name,
            user_id: user_id,
            user_info: user_info,
            avatar: avatar
          }
        })
      })

    删:

    Router.get('/cleardata', function(req,res) {
      // 清空全部数据
      poetrylist.destroy({
        // where: {id: 123}
        // 这里可以根据我们定义的条件删除满足条件的数据
      }).then((doc) => {
        return res.json({
          code: 0,
          data: doc
        })
      })
    })

    改:

    Router.post('/updataUserInfo', function(req,res) {
      // 完善用户信息
      const user_id = req.cookies.user_id
      const user_info = req.body.userinfo
      account.update(
        user_info, // 这里是我们要更新的字段,使用逗号隔开
        {
          'where': {
            'user_id': user_id // 这里是我们要更新那条数据的条件
          }
        }
      ).then((doc) => {
        return res.json({
          code: 0,
          data: {
            user_info: user_info
          }
        })
      })
    })

    查:

    Router.post('/getUserInfo', function(req,res) {
      // 完善用户信息
      const user_id = req.body.user_id ? req.body.user_id : req.cookies.user_id
      account.findOne({
        'where': {'user_id': user_id},
        // attributes属性可以指定返回结果,返回那些字段的信息
        attributes: ['user_name', 'avatar', 'user_info', 'user_fans', 'attention', 'poetry_num', 'user_id']
      }).then((doc) => {
        poetrylist.findAll({
          where: {'user_id': user_id},
          order: [
            ['create_temp', 'DESC'],
          ]
        }).then((metadata) => {
          return res.json({
            code: 0,
            data: {
              user_info: doc,
              list: metadata
            }
          })
        })
      })
    })

    这里使用的是findOne,还有findAll,
    findById等等,具体参考官方文档
    
    

    三、模型关系

    这里就要就要求我们指定数据表之间的关系,这里直说关系,详解请看官方文档

    1.一对一(BelongsTo, HasOne )

    一对一关联是由一个单一的外键,实现两个模型之间的精确关联。
    
    BelongsTo关联表示一对一关系的外键存在于源模型。
    var Player = this.sequelize.define('player', {/* attributes */})
      , Team  = this.sequelize.define('team', {/* attributes */});
    
    Player.belongsTo(Team); // 会为Player添加一个teamId 属性以保持与Team 主键的关系
    默认情况下,一个属于关系的外键将从目标模型的名称和主键名称生成。
    目标键是位于目标模型上通过源模型外键列指向的列。默认情况下,目标键是会belongsTo关系中目标模型的主键。要使用自定义列,请用targetKey选项来指定
    
    HasOne关联表示一对一关系的外键存在于目标模型。
    虽然被称为HasOne 关联,但大多数 1:1关系中通常会使用BelongsTo 关联,因为BelongsTo 会在源模型中添加外键,而HasOne 则会在目标模型中添加外键。
    HasOne 与BelongsTo 的不同
    
    在1:1 的关系中,可使用HasOne 或BelongsTo来定义。但它们的使用场景有所不同

    2.一对多(HasMany)

    One-To-Many关联是指一个源模型连接多个目标模型。反之目标模型都会有一个明确的源。
    
    var User = sequelize.define('user', {/* ... */})
    var Project = sequelize.define('project', {/* ... */})
     
    // 定义 hasMany 关联
    Project.hasMany(User, {as: 'Workers'})
    会向 User 中添加一个projectId或project_id属性。Project 的实例中会有访问器getWorkers 和 setWorkers。这是一种单向关联方式,如果两个模型间还有其它关联方式请参考下面的多对多关系。

    3.多对多(Belongs-To-Many)

    多对多(Belongs-To-Many)关联
    Belongs-To-Many 关联是指一个源模型连接多个目标模型。而且,目标模型也可以有多个相关的源。
    
    Project.belongsToMany(User, {through: 'UserProject'});
    User.belongsToMany(Project, {through: 'UserProject'});
    这会创建一个新模型UserProject其中会projectId和userId两个外键。是否使用驼峰命名取决与相关联的两个表。
    
    定义through选项后,Sequelize会尝试自动生成名字,但并一定符合逻辑。
    
    在本例中,会为User添加方法 getUsers, setUsers, addUser,addUsers to Project, and getProjects, setProjects, addProject, and addProjects
    
    有时我们会对连接的模型进行重命名,同样可以使用as实现。

    四、多表联查(我们进行用户信息模型和文章模型的联合查询)如下图的结果

    const sequelize = require('./db')
    const account = sequelize.model('account') // 获取模型
    const poetrylist = sequelize.model('poetrylist')
    poetrylist.belongsTo(account, {foreignKey: 'user_id', targetKey: 'user_id'}); // 指定模型关系可查询的外键字段
    Router.get('/getPoetryList', function(req, res) {
      // 获取文章列表
      poetrylist.findAll({
        include: [{ // 通过include字段执行要联合那个模型进行查询
          model: account, // 执行模型
          attributes: ['user_name', 'avatar', 'user_id'] // 想要只选择某些属性可以使用 attributes: ['foo', 'bar']
        }],
        attributes: [
          'content',
          'poetrylist_id',
          'recommend',
          'star',
          'user_id',
          'create_temp',
          'guest_num',
          'transmit_content',
          'transmit_user_id',
          'transmit_user_name',
          'transmit_poetrylist_id',
          'id'],
        order: [ // 使用order进行排序
          ['create_temp', 'DESC'], // 这;i按照时间顺序进行排序
        ]
      }).then((doc) => {
        supportlist.findAll({
          // 获取当前用户的点赞文章的列表
          where: {
            "user_id": req.cookies.user_id
          }
        }).then(suplist => {
          // 数据处理
          for (let i = 0; i < doc.length; i++) {
            doc[i].dataValues.isAttention = false
            if (suplist.length) {
              for (let j = 0; j < suplist.length; j++) {
                if (doc[i].dataValues.poetrylist_id === suplist[j].dataValues.poetrylist_id){
                  doc[i].dataValues.isAttention = true
                }
              }
            } else {
              doc[i].dataValues.isAttention = false
            }
          }
          return res.json({
            code: 0,
            data: doc,
            suplist: suplist
          })
        })
      })
    })

    以上查询代码转换位sql语句为:

    五、事物

    Transaction是Sequelize中用于实现事务功能的子类,通过调用Sequelize.transaction()方法可以创建一个该类的实例。在Sequelize中,支持自动提交/回滚,也可以支持用户手动提交/回滚。

    Sequelize有两种使用事务的方式:

    • 基于Promise结果链的自动提交/回滚
    • 另一种是不自动提交和回滚,而由用户控制事务

    受管理的事务(auto-callback)

    受管理的事务会自动提交或回滚,你可以向sequelize.transaction方法传递一个回调函数来启动一个事务。

    需要注意,在这种方式下传递给回调函数的transaction会返回一个promise链,在promise链中(thencatch)中并不能调用t.commit()t.rollback()来控制事务。在这种方式下,如果使用事务的所有promise链都执行成功,则自动提交;如果其中之一执行失败,则自动回滚。

    return sequelize.transaction(function (t) {
    
      // 要确保所有的查询链都有return返回
      return User.create({
        firstName: 'Abraham',
        lastName: 'Lincoln'
      }, {transaction: t}).then(function (user) {
        return user.setShooter({
          firstName: 'John',
          lastName: 'Boothe'
        }, {transaction: t});
      });
    
    }).then(function (result) {
      // Transaction 会自动提交
      // result 是事务回调中使用promise链中执行结果
    }).catch(function (err) {
      // Transaction 会自动回滚
      // err 是事务回调中使用promise链中的异常结果
    });

    不受管理的事务(then-callback)

    不受管理的事务需要你强制提交或回滚,如果不进行这些操作,事务会一直保持挂起状态直到超时。

    启动一个不受管理的事务,同样是调用sequelize.transaction()方法,但不传递回调函数参数(仍然可以传递选项参数)。然后可以在其返回的promisethen方法中手工控制事务:

    Router.post('/subscription', function (req, res) {
      // 关注功能
      const data = {
        user_id: req.cookies.user_id,
        target_id: req.body.target_id
      }
      // Transaction是Sequelize中用于实现事务功能的子类,
      // 通过调用Sequelize.transaction()方法可以创建一个该类的实例。
      // 在Sequelize中,支持自动提交/回滚,也可以支持用户手动提交/回滚。
      return sequelize.transaction({
        autocommit: true
      }, t => {
        return attentionlist.findOne({
          'where': {
            'user_id': req.cookies.user_id,
            'target_id': req.body.target_id
          }
        },{transaction: t}).then(doc => {
          if (!doc) {
            return attentionlist.create(data,{transaction: t}).then(ret => {
              return account.findOne({
                'where': {'user_id': req.cookies.user_id}
              }, {transaction: t}).then(rets => {
                // increment自增函数
                return rets.increment('attention').then(retss => {
                  
                  return 'success'
                })
              })
            }, {transaction: t}).then(docs => {
              return docs
            })
          } else {
            return 100
          }
        })
      }).then(result => {
        return res.json({
          code: 0,
          data: result
        })
      })
    })

     项目地址:https://github.com/songdongdong123/vue_chat

  • 相关阅读:
    mysql-community-server-5.7.24 & 5.7.31 (5.6.35 升级到 5.7.24)
    企业 数据 能力 中台 大数据平台 CRM
    Tomcat日志切割配置
    你不知道的 Blob
    细说websocket快速重连机制
    DNS反向查询
    从安全的角度看待DNS
    LVS 负载均衡集群
    Linux服务器配置DNS解析
    react修改state的值
  • 原文地址:https://www.cnblogs.com/songdongdong/p/9408351.html
Copyright © 2011-2022 走看看