nodejs sequelize框架中association使用教程

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

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

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

// in User model
associate: function(models){
        User. hasOne(models.UserInfo); 
}
//in UserInfo model
associate: function(models){
        UserInfo.belongsTo(models.User);
}

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

models.User.findOne({
        where:{ id: userid },
        include: {model: models.UserInfo, as: 'Info'}
    }).then(function(user){
         /*{
            name: 'xxx',
            UserInfo: {
                email: 'xxx'
            }
        }*/
    });
models.User.findOne({
    where:{id: id}
}).then(function(user){
    user.getUserInfo().then(function(info){
        /*{
            email:'xxx',
            sex: 'male',
            profile: 'usl:xxx'
        }
        */
    })
});

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

/*in User model*/
associate: function(models) {     
   User.hasMany(models.Topic, {as: 'AuthorTopics', foreignKey: 'authorId'});
   User.belongsToMany(models.Topic, {as: 'WatchedTopics', through: 'UserWatchedTopic'});
   User.belongsToMany(models.Topic, {as: 'CommentedTopics', through: models.UserCommentTopic});
}
/*in Topic*/
associate: function(models) {     
   Topic.belongsTo(models.User, {as: 'Author', foreignKey: 'authorId'});
   Topic.belongsToMany(models.User, {as: 'Watchors', through: 'UserWatchedTopic'});
   Topic.belongsToMany(models.User, {as: 'Commenters', through: models.UserCommentTopic});
}

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

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

models.Topic.findOne({
      where: {id: id}
}).then(function(topic){
     topic.getWatchors().then(function(watchers){
            /*
         [{watcher1}{watcher2}{watcher3}] 
      */
    })
})

node.js sequelize orm 框架多表关联

使用sql数据库最基本的ORM映射之外肯定还有关系映射,sequelize能让你使用最少的代码实现最复杂的映射

比如:
一个文章model和一个文章分类model的关系描述。
Article.js 文章Model

var Article = sequelize.define("info",{
    id: {type: Sequelize.UUIDV4, primaryKey: true, defaultValue: Sequelize.UUIDV4},
    category_id: {type:Sequelize.STRING(36),allowNull:false},
    title:{type:Sequelize.STRING(200),allowNull:false},
    content:{type:Sequelize.TEXT,allowNull:false},
    imgurl:{type:Sequelize.STRING(100)},
    remark:{type:Sequelize.STRING(200)},
    ispublished:{type:Sequelize.BOOLEAN,allowNull:false},
    creator_id:{type:Sequelize.STRING(36),allowNull:false},
    createtime:{type:Sequelize.DATE,defaultValue:Sequelize.now},
    publishtime:{type:Sequelize.DATE,defaultValue:Sequelize.now},
    publisher_id:{type:Sequelize.STRING(36),allowNull:false}
});
Article.belongsTo(Category,{as:'Category',foreignKey:'category_id'});
Article.belongsTo(Staff,{as:'Creator',foreignKey:'creator_id'});
Article.belongsTo(Staff,{as:'Publisher',foreignKey:'publisher_id'});
Category.hasMany(Article,{as:'Articles',foreignKey:'category_id'});
Category.belongsTo(Staff,{as:'Creator',foreignKey:'creator_id'});
Category.belongsTo(Staff,{as:'Publisher',foreignKey:'publisher_id'});
module.exports = Article;

分类

var Category = sequelize.define("category",{
    id: {type: Sequelize.UUIDV4, primaryKey: true, defaultValue: Sequelize.UUIDV4},
    name: {type:Sequelize.STRING(50),allowNull:false},
    bigimgurl:{type:Sequelize.STRING(200)},
    smallimgurl:{type:Sequelize.STRING(200)},
    platecode:{type:Sequelize.INTEGER},
    remark:{type:Sequelize.STRING(200)},
    ispublished:{type:Sequelize.BOOLEAN,allowNull:false},
    creator_id:{type:Sequelize.STRING(36),allowNull:false},
    createtime:{type:Sequelize.DATE,defaultValue:Sequelize.now},
    publishtime:{type:Sequelize.DATE,defaultValue:Sequelize.now},
    publisher_id:{type:Sequelize.STRING(36),allowNull:false}
});
module.exports = Category;

Article.belongsTo(Category,{as:'Category',foreignKey:'category_id'});表示文章属于一个分类,也就是一对一关系。使用‘foreignKey’来标识外键。
Category.hasMany(Article,{as:'Articles',foreignKey:'category_id'}); 表示一个分类下有多个文章(当然也可以在‘Article’里面使用belongsToMany来表示)

最新版的sequelize多对多关系双方都是 hasMany 或belongsToMany来表示sequelize会抛出红色警告,建议双向使用’belongsToMany’即可。

上面的关系描述我为什么都卸载Article.js里面呢?是因为requere加载顺序原因,如果分开写,后加在的model会未初始化完成! 所以要么把所有model写到一个文件(这份方法显然无法接受),所以这种就把关系描述全部丢到关系中个人认为最常用最容易注意到的Model中。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索as
, 代码
, 模型
用户
nodejs sequelize、nodejs sequelizejs、nodejs orm sequelize、sequelize 中文教程、sequelize 教程,以便于您获取更多的相关知识。

时间: 2024-08-02 19:31:21

nodejs sequelize框架中association使用教程的相关文章

NodeJS Express框架中处理404页面一个方式_javascript技巧

在用 Express 的时候,路由是我最困惑的事之一.知道用 app.get('*') 可以处理所有页面,但这样除了自定义的其他路由外,静态文件是被忽略的.最近在写一个小工具的时候,找到了一个解决方案: 复制代码 代码如下: var express = require('express'),    router = require('./routes');     var app = module.exports = express.createServer(); // Configuratio

Yii框架中memcache使用教程

我做的项目是一个手机排行榜,但是排行榜每隔15分钟刷新一次啊,排行榜有一个前三名,可能前15分钟这三个人是前三名,也许下一个15分钟又是别人前三名了,产品要求,这些人中只要是前三名的都要发奖品,思考了好久,最终决定用memcache来保存每15分钟的榜单前三名的信息.代码如下:  代码如下 复制代码 public function getChargeRank3()     {         $startime='2014-04-10 00:00:00';         $endtime='2

如何在Python的Flask框架中使用模版的入门教程

  如何在Python的Flask框架中使用模版的入门教程?          概述 如果你已经阅读过上一个章节,那么你应该已经完成了充分的准备工作并且创建了一个很简单的具有如下文件结构的Web应用: microblog |-flask文件夹 |-<一些虚拟环境的文件> |-app文件夹 | |-static文件夹 | |-templates文件夹 | |-__init__.py文件 | |-views.py文件 |-tmp文件夹 |-run.py文件 以上给你介绍了在Python的Flask

Python的Flask框架中实现分页功能的教程

  这篇文章主要介绍了Python的Flask框架中实现分页功能的教程,文中的示例基于一个博客来实现,需要的朋友可以参考下 Blog Posts的提交 让我们从简单的开始.首页上必须有一张用户提交新的post的表单. 首先我们定义一个单域表单对象(fileapp/forms.py): ? 1 2 class PostForm(Form): post = TextField('post', validators = [Required()]) 下面,我们把这个表单添加到template中(file

Python的Flask框架中实现简单的登录功能的教程

  Python的Flask框架中实现简单的登录功能的教程,登录是各个web框架中的基础功能,需要的朋友可以参考下 回顾 在前面的系列章节中,我们创建了一个数据库并且学着用用户和邮件来填充,但是到现在我们还没能够植入到我们的程序中. 两章之前,我们已经看到怎么去创建网络表单并且留下了一个实现完全的登陆表单. 在这篇文章中,我们将基于我门所学的网络表单和数据库来构建并实现我们自己的用户登录系统.教程的最后我们小程序会实现新用户注册,登陆和退出的功能. 为了能跟上这章节,你需要前一章节最后部分,我们

在Python的Flask框架中实现单元测试的教程

  在Python的Flask框架中实现单元测试的教程,属于自动化部署的方面,可以给debug工作带来诸多便利,需要的朋友可以参考下 概要 在前面的章节里我们专注于在我们的小应用程序上一步步的添加功能上.到现在为止我们有了一个带有数据库的应用程序,可以注册用户,记录用户登陆退出日志以及查看修改配置文件. 在本节中,我们不为应用程序添加任何新功能,相反,我们要寻找一种方法来增加我们已写代码的稳定性,我们还将创建一个测试框架来帮助我们防止将来程序中出现的失败和回滚. 让我们来找bug 在上一章的结尾

Python的Django框架中TEMPLATES项的设置教程

  这篇文章主要介绍了Python的Django框架中TEMPLATES项的设置教程,主要针对Django1.8后的新特性,需要的朋友可以参考下 TEMPLATES Django 1.8的新特性 一个列表,包含所有在Django中使用的模板引擎的设置.列表中的每一项都是一个字典,包含某个引擎的选项. 以下是一个简单的设定,告诉Django模板引擎从已安装的应用程序(installed applications)的templates子目录中读取模板: ? 1 2 3 4 5 6 TEMPLATES

在Python的Tornado框架中实现简单的在线代理的教程

  这篇文章主要介绍了在Python的Tornado框架中实现简单的在线代理的教程,代理功能是一个常见的网络编程实现,需要的朋友可以参考下 实现代理的方式很多种,流行的web服务器也大都有代理的功能,比如http://www.tornadoweb.cn用的就是nginx的代理功能做的tornadoweb官网的镜像. 最近,我在开发一个移动运用(以下简称APP)的后台程序(Server),该运用需要调用到另一平台产品(Platform)的API.对于这个系统来说,可选的一种实现方式方式是APP同时

在Python的Flask框架中使用日期和时间的教程

  这篇文章主要介绍了在Python的Flask框架中使用日期和时间的教程,包括对各个时区之间转换的一些处理,需要的朋友可以参考下 时间戳的问题 我们的微博应用的一个忽略了很久的问题就是日间和日期的显示. 直到现在,我们在我们的User和Post对象中使用Python它自己的方式来渲染时间对象,但这并不是一个好的解决方案. 考虑下这样的例子.我正在写这篇文章,此时正是12月31号下午3:54.我的时区是PST(或者你们更习惯的:UTC-8). 在Python解释器中运行,我得到下面输出: ? 1