• 热门专题

sequelize中的association使用讲解 nodejs

作者:爱上读书  发布日期:2015-08-11 22:31:06
  • 注:本文使用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.

     

延伸阅读:

About IT165 - 广告服务 - 隐私声明 - 版权申明 - 免责条款 - 网站地图 - 网友投稿 - 联系方式
本站内容来自于互联网,仅供用于网络技术学习,学习中请遵循相关法律法规