sequelize中的association使用讲解,nodejs

注:本文使用sequelize 1.7.0。所举例子均已通过测试,可以放心使用。

使用sequelize能够较为方便的按照MVC模式组织nodejs程序后端架构。这篇文章,就笔者认为,其中较为有用且稍有难度的association进行分享。

通常,模型之间共有三种关系,1:1,1:n,n:m。以下举例逐个击破。

1:1.假如有user和userinfo俩个模型,分别对应用户,以及用户的资料。此时,每个用户应当有且只有一个用户资料,由此,user与uerinfo的关系应当为1:1.在sequelize中,使用hasOne与belongsTo进行描述。在实际的模型中

1 // in User model
2 associate: function(models){
3         User. hasOne(models.UserInfo);
4 }
5 //in UserInfo model
6 associate: function(models){
7         UserInfo.belongsTo(models.User);
8 }

上边这段代码中,讲的就是,一个User有一个UserInfo,一个UserInfo反过来属于一个User。由此双方关系确立。运行代码后,sequelize会自动在UserInfo中增加一个外键UserId.在搜索的时候如果需要获取UserInfo,可以使用下面俩种方式:

 1 models.User.findOne({
 2         where:{ id: userid },
 3         include: {model: models.UserInfo, as: ‘Info‘}
 4     }).then(function(user){
 5          /*{
 6             name: ‘xxx‘,
 7             UserInfo: {
 8                 email: ‘xxx‘
 9             }
10
11         }*/
12     });
13 models.User.findOne({
14     where:{id: id}
15 }).then(function(user){
16     user.getUserInfo().then(function(info){
17         /*{
18             email:‘xxx‘,
19             sex: ‘male‘,
20             profile: ‘usl:xxx‘
21         }
22         */
23     })
24 });    

1:n.假如一个人要发博客,那么一个人User应当会发很多篇博文Article,这样User和Article之间的关系就可以恰当的表示为1:n。类比1:1的描述方式,sequelize中使用hasMany与belongsTo进行表示。代码与1:1中雷同,就此不再啰嗦。

n:m。这个相比前俩者而言是较为复杂的,讲解这个实际上是这篇博文的主要目的所在。为了更为全面深入的讲解,特别举一个非常复杂的例子。俩个模型分别为用户User和文章Topic。他们之间的关系有:(1:n)用户写了很多篇文章,每个文章只有一个作者;(n:m)假如有收藏功能,用户会收藏一些文章,每篇文章也会被很多人所收藏。本来就此就可以了,但是为了增加复杂度,特地再引入一种n:m关系,文章被用户所评价。sequelize是使用belongsToMany来表示n:m的关系的。在这种多对多的关系中,特别像本文这种情况,有多种多对多关系,为了更为清晰的描述,通常会引入另外一张关系表。具体请参考如下代码:

 1 /*in User model*/
 2 associate: function(models) {
 3    User.hasMany(models.Topic, {as: ‘AuthorTopics‘, foreignKey: ‘authorId‘});
 4    User.belongsToMany(models.Topic, {as: ‘WatchedTopics‘, through: ‘UserWatchedTopic‘});
 5    User.belongsToMany(models.Topic, {as: ‘CommentedTopics‘, through: models.UserCommentTopic});
 6 }
 7 /*in Topic*/
 8 associate: function(models) {
 9    Topic.belongsTo(models.User, {as: ‘Author‘, foreignKey: ‘authorId‘});
10    Topic.belongsToMany(models.User, {as: ‘Watchors‘, through: ‘UserWatchedTopic‘});
11    Topic.belongsToMany(models.User, {as: ‘Commenters‘, through: models.UserCommentTopic});
12 }

上述俩种n:m关系分别使用了俩张表UserWatchedTopic, UserCommentTopic来描述。UserWatchedTopic直接使用字符串,适用于简单的多对多关系。当我们想记录这种n:m的关系中一些二外的信息,比如,当前想把第一种是否为作者合并到n:m得关系中,此时可在UserCommentTopic中增加isAuthor字段进行标记。当然,笔者认为这样会使得关系复杂化,损害脑细胞。

假如我们要获取一篇文章的关注者时,可以这样:

1 models.Topic.findOne({
2       where: {id: id}
3 }).then(function(topic){
4      topic.getWatchors().then(function(watchers){
5             /*
6          [{watcher1}{watcher2}{watcher3}]
7       */
8     })
9 })

That‘s it.

如有疑问,欢迎随时讨论。[email protected]

时间: 2024-12-28 12:21:44

sequelize中的association使用讲解,nodejs的相关文章

详细讲解nodejs中使用socket的私聊的方式

详细讲解nodejs中使用socket的私聊的方式 在上一次我使用nodejs+express+socketio+mysql搭建聊天室,这基本上就是从socket.io的官网上的一份教程式复制学习,然后,根据国情,我又在其中加入了私聊点对点,然后共享画图的你画我猜功能. 先上效果图: 由于本人太穷,所以服务器和数据库都是使用的国外免费的.域名是我的,它的访问地址是:http://chat.lovewebgames.com 先说下我对socket.io的理解,websocket更像是开启了一个端口

Android开发中Flag参数的讲解

Android开发中Flag参数的讲解: Intent对象在Android开发中起着举足轻重的作用,其内置了丰富的常量,用于传递数据, 下面本文将介绍跟Task有关的一些Flag参数,各参数的理解均来自Android API和本人在实际项目中的体验,如果有描述不当之处,还请各位不吝赐教. 1.FLAG_ACTIVITY_BROUGHT_TO_FRONT:不在程序代码中设置,在launchMode中设置singleTask模式时系统帮你设定. 2.FLAG_ACTIVITY_CLEAR_TOP:清

关于Linux系统中sed编辑器详细讲解

一.sed简介 sed是非交互式的编辑器.它默认不不编辑源文件,仅仅对模式空间中的数据做处理,并将模式空间中的内容显示在屏幕上.sed编辑器是逐行处理文件,并将结果发送到屏幕.具体过程如下: 首先sed把当前正在处理的行保存在一个临时缓存区中(也称为模式空间),然后处理临时缓冲区中的行,完成后把该行发送到屏幕上.sed每处理完一行就将其从临时缓冲区删除,然后将下一行读入,进行处理和显示.处理完输入文件的最后一行后,sed便结束运行.sed把每一行都存在临时缓冲区中,对这个副本进行编辑,所以不会修

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

nodejs(第三篇):nodejs中的文件模块、nodejs中的require与exports、http模块补充、JavaScript Standard Style

一.nodejs中的文件模块 在nodejs中,用户自己编写的模块,称为文件模块. 文件模块,则是指js文件.json文件或者是.node文件.在引用文件模块的时候后要加上文件的路径:/.../.../xxx.js表示绝对路径../xxx.js表示相对路径(同一文件夹下的xxx.js),../表示上一级目录.如果既不加/.../.../又不加./的话,则该模块要么是核心模块,要么是从一个node_modules文件夹加载. (1)在Node.js中,require是一个方法,只有通过requir

转!!MySQL中的存储引擎讲解(InnoDB,MyISAM,Memory等各存储引擎对比)

MySQL中的存储引擎: 1.存储引擎的概念 2.查看MySQL所支持的存储引擎 3.MySQL中几种常用存储引擎的特点 4.存储引擎之间的相互转化 一.存储引擎: 1.存储引擎其实就是如何实现存储数据,如何为存储的数据建立索引以及如何更新,查询数据等技术实现的方法. 2.MySQL中的数据用各种不同的技术存储在文件(或内存)中,这些技术中的每一种技术都使用不同的存储机制,索引技巧,锁定水平并且最终提供广泛的不同功能和能力.在MySQL中将这些不同的技术及配套的相关功能称为存储引擎. 二.MyS

HTML5游戏开发中基础的Tag讲解

一般在HTML5游戏开发中,基础的Tag都用在标题,段落以及分行上,下面就来讲解下几种最常用的Tag.当然最好用的HTML5学习方式就是跟随示例,今天我们的HTML5游戏开发教程也从实例开始. 首先来看一下标题中的Tag应用.在HTML5游戏开发中,我们用从h1至h6的几个Tag来定义文章的标题,每个正文中的标题都是自成一段的.例如这样: <html>  <head></head>  <body>   <h1>This is a heading&

HTTP中header的信息讲解以及设置

HTTP消息中header头部信息的讲解 本文导读:HTTP消息包括客户机向服务器的请求消息和服务器向客户机的响应消息.这两种类型的消息由一个起始行,一个或者多个头域,一个只是头域结束的空行和可选的消息体组成.HTTP的头域包括通用头,请求头,响应头和实体头四个部分.每个头域由一个域名,冒号(:)和域值三部分组成 HTTP Request的Header信息 1.HTTP请求方式 如下表: GET 向Web服务器请求一个文件 POST 向Web服务器发送数据让Web服务器进行处理 PUT 向Web

FreeSWITCH IVR中lua调用并执行nodejs代码

一.功能需求: 通过FreeSWITCH的IVR按键调用相应的脚本文件:nodejs提供很多的模组,可以方便的与其它系统或者进行任何形式的通讯,我的应用是通过nodejs发送http post请求: 由于不太熟悉FreeSWITCH直接调动执行nodejs文件的方法,所以我通过执行Lua脚本,在lua脚本中执行对nodejs文件的调用并执行,具体的设定记录如下: 二.具体设定: ①IVR设定: <entry action="menu-exec-app" digits="