使用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 教程,以便于您获取更多的相关知识。