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.

如有疑問,歡迎隨時討論。fangbolang@163.com

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM