一个关于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
    })
  })
})

结束:一共写了四篇文章,也不知道说清楚了没有,好多觉得该说的,大家应该都会知道,所以没有很详细的进行说明,如果还有不清楚的地方可以参考github上的源码:https://github.com/songdongdong123/vue_chat

原文地址:https://www.cnblogs.com/songdongdong/p/9408351.html

时间: 2024-08-29 04:13:40

一个关于vue+mysql+express的全栈项目(四)------ sequelize中部分解释的相关文章

一个关于vue+mysql+express的全栈项目(二)------ 前端构建

一.使用vue-cli脚手架构建 1 <!-- 全局安装vue-cli --> 2 npm install -g vue-cli 3 <!-- 设置vue webpack模板 --> 4 vue init webpack my-project 5 <!-- 进入项目 --> 6 cd my-project 7 <!-- 安装依赖 --> 8 npm install 9 <!-- 启动项目 --> 10 npm run dev 二.安装axios并

一个关于vue+mysql+express的全栈项目(五)------ 实时聊天部分socket.io

一.基于web端的实时通讯,我们都知道有websocket,为了快速开发,本项目我们采用socket.io(客户端使用socket.io-client) Socket.io是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用.它会自动根据浏览器从WebSocket.AJAX长轮询.Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5 socket.io特点: 实

《从零开始做一个MEAN全栈项目》(1)

欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习. 在本系列的开篇,我打算讲一下全栈项目开发的优势,以及MEAN项目各个模块的概览. 为什么选择全栈开发?     对于初学者来说,学习一门新的语言和技术的体验总是让人愉快的,也会满足于掌握了一些新的东西并且解决了一些实际问题.在一个小组中采用全栈开发时,你可以更加有效地把握项目全局概念,这也有利于让你了解项目中的不同模块以及它们之间是如何协同工作的.你会对你们的产品中他人的贡献更加清晰,你也就了解了这款产品如何

《从零开始做一个MEAN全栈项目》(2)

欢迎关注本人的微信公众号"前端小填填",专注前端技术的基础和项目开发的学习.   上一节简单介绍了什么是MEAN全栈项目,这一节将简要介绍三个内容:(1)一个通用的MEAN项目的技术架构,(2)为什么我们要打造单页应用,(3)本系列项目的技术架构和开发计划.希望通过这三个问题,我们能够对本项目产生一个全局视角. 实现一个常见的MEAN全栈项目的核心就是RESTful API.这个接口通常是用MongoDB, Express, Node.js实现的,而单页应用(SPA)由AngularJ

Vue+Node+MongoDB高级全栈开发

第1章 本地与服务器环境准备介绍微信公众号/小程序/域名/服务器的申请选购流程,在本地与线上服务器分别对项目的运行环境进行搭建部署,如 Node.js/Vue/Yarn/PM2/Nginx/MongoDB 等等,同时会来简单介绍下从本地通过 PM2 利用 Git 仓库直接往线上服务器部署以及 Nginx 端口映射解析特定域名的实现流程,最终准备好本地线上和外部业务环境为开发...1-1 导学1-2 课程简介1-3 申请认证公众服务号与小程序1-4 选购域名与备案解析域名1-5 选购配置服务器1-

VueCli3.0全栈项目-资金管理系统带权限(node/element/vue)

课程简介:通过本系列课程,可以快速的掌握全栈开发流程, 包括node.js的接口搭建, vue前端项目的构建, element-ui视图的构建. 一套应有尽有的课程! 课程目录:1.Vue全栈-最终成果展示.mp42.Node接口搭建-express搭建服务器.mp43.Node接口搭建-连接MongoDB数据库.mp44.Node接口搭建-搭建路由和数据模型.mp45.Node接口搭建-搭建注册接口并存储数据.mp46.Node接口搭建-使用全球公认头像gravatar.mp47.Node接口

前端面试题总结(js、html、小程序、React、ES6、Vue、算法、全栈热门视频资源)持续更新 &#362414;

原文: http://blog.gqylpy.com/gqy/438 置顶:来自一名75后老程序员的武林秘籍--必读(博主推荐) 来,先呈上武林秘籍链接:http://blog.gqylpy.com/gqy/401/ 你好,我是一名极客!一个 75 后的老工程师! 我将花两分钟,表述清楚我让你读这段文字的目的! 如果你看过武侠小说,你可以把这个经历理解为,你失足落入一个山洞遇到了一位垂暮的老者!而这位老者打算传你一套武功秘籍! 没错,我就是这个老者! 干研发 20 多年了!我也年轻过,奋斗过!我

“全栈2019”Java第九章:解释第一个程序

难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第九章:解释第一个程序 下一章 "全栈2019"Java第十章:关键字 学习小组 加入同步学习小组,共同交流与进步. 方式一:关注头条号Gorhaf,私信"Java学习小组". 方式二:关注公众号Gorhaf,回复"Java学习小组". 全栈工程师学习

全栈项目|小书架|服务器端-NodeJS+Koa2实现首页图书列表接口

通过上篇文章 全栈项目|小书架|微信小程序-首页水平轮播实现 我们实现了前端(小程序)效果图的展示,这篇文章来介绍服务器端的实现. 首页书籍信息 先来回顾一下首页书籍都有哪些信息: 从下面的图片可以看出目前一本图书信息主要有: 图片字段 名称字段 作者字段 出版社字段 除了以上前端页面中可见的信息外,在服务器开发中还需要给每一条记录(数据)都加上下面的几个字段: 创建时间字段 更新时间字段 删除时间字段 最后完成的数据库表如下: ps:由于数据库是直接导入的,之前的数据库是没有时间字段的,所以前