前言,最近在研究nodeJs,新手上车,使用mysql的ORM库Sequelize,其中many-to-many,属于ToMany的创建,查询,更新摸索几天下来,写下了以下内容。由于你用的是Sequelize,不想使用原生的sql语句,所以本文对原生sql高手没有影响,对Sequelize高手也没有影响(反而希望大家多多指点)。只是希望能给刚入门Sequelize意义的胖友们一个参考。Sequelize的安装,链接mysql,简单的增删改查都不会繁琐。我可以到处搜索。以下仅适用于belongsToMany。我们假设有这样一种场景,一篇文章(Post)可以有多个标签(Tags)。同样,一个Tag也可以对应多个Post。我们需要一张关联表PostTag来记录Posts和Tags之间的关系。一、表结构//tag表sequelize.define('tag',{name:{type:DataTypes.STRING(20),allowNull:false},createdAt:{type:DataTypes.DATE,get(){returnmoment(this.getDataValue('createdAt')).format('YYYY-MM-DDHH:mm:ss');}},updatedAt:{type:DataTypes.DATE,get(){returnmoment(this.getDataValue('updatedAt')).format('YYYY-MM-DDHH:mm:ss');}}},{freezeTableName:true})//Post表sequelize.define('post',{name:{type:DataTypes.STRING(20),allowNull:false},createdAt:{type:DataTypes.DATE,get(){returnmoment(this.getDataValue('createdAt')).format('YYYY-MM-DDHH:mm:ss');}},updatedAt:{type:DataTypes.DATE,get(){returnmoment(this.getDataValue('updatedAt')).format('YYYY-MM-DDHH:mm:ss');}}},{freezeTableName:true})//PostTag表sequelize.define('postTag',{id:{type:DataTypes.INTEGER,primaryKey:true,autoIncrement:true},postId:{type:DataTypes.INTEGER,allowNull:false,unique:'postTag'},tagId:{type:DataTypes.INTEGER,unique:'postTag',allowNull:false,引用:null},createdAt:{type:DataTypes.DATE,get(){returnmoment(this.getDataValue('createdAt')).format('YYYY-MM-DDHH:mm:ss');}},updatedAt:{类型:数据类型。DATE,get(){返回时刻(this.getDataValue('updatedAt')).format('YYYY-MM-DDHH:mm:ss');}}},{freezeTableName:true})2.建立关联关系constSequelize=require('../config/db')constPostTag=Sequelize.import('../schema/postTag.js')constTag=Sequelize.import('../schema/tag.js')constPost=Sequelize.import('../schema/post.js')//表需要先同步,请自行处理,//例如PostTag.sync({force:false});Post.belongsToMany(Tag,{through:{model:PostTag,unique:false,},foreignKey:'postId',//通过外键postId约束:false});Tag.belongsToMany(发布,{through:{model:PostTag,unique:false,},foreignKey:'tagId',//通过外键tagIdconstraints:false});提示关系后,Post会自动添加addTags、getTags、setTags方法Tag会自动添加addPosts、getPosts、setPosts方法。3.Createstaticasynccreate(data){//比如我们的tag表有2条数据,[{id:1,name:'tag1'},{id:2,name:'tag2'}]//传入的数据={name:'文章1',tagIds:[1,2]}letnewPost=awaitPost.create({name:data.name});//返回创建的post对象lettags=awaitTag.findAll({where:{id:data['tagIds']}})//找到对应的tagId对象awaitnewPost.setTags(tags)//添加一条记录到postTag表通过setTags方法返回true//以上操作会给post表新建一条记录,{id:1,name:'文章1'}//向postTag表添加2条记录,[{id:1,postId:1,tagId:1},{id:2,post:1,tagId:2}]}4.关联查询staticasyncallPost(){returnawaitPost.findAll({include:[{model:tag,attributes:['id','name']}]});}//查询结果{"code":200,"msg":"查询成功!","data":[{"createdAt":"2018-12-1013:18:11","updatedAt":"2018-12-1013:18:11","id":1,"name":"第1条","tags":[{"createdAt":"2018-12-1013:21:37","updatedAt":"2018-12-1013:21:37","id":1,"name":"标签1","postTag":{"createdAt":"2018-12-1013:18:11","updatedAt":"2018-12-1013:18:11","id":1,"postId":1,"tagId":1}},{"createdAt":"2018-12-1013:21:37","updatedAt":"2018-12-1013:21:37","id":2,"name":"标签2","postTag":{"createdAt":"2018-12-1013:18:11","updatedAt":"2018-12-1013:18:11","id":2,"postId":1,"tagId":2}}]}]}五、updatestaticasyncupdatePost(id,data){//id为需要修改的ID,data={name:'修改文章',tagIds:[1]}lettags=awaitTag.findAll({where:{id:data['tagIds']}})Post.findByPk(id).then(function(post){post.update({name:data.name})post.setTags(tags)})returntrue}六、在事务多表??更新中,我们总是担心哪个步骤出错,导致后期难以维护。这里可以使用事务来处理该步骤出错后自动回滚。我将写一个创建步骤的示例。staticasynccreate(data){lettags=awaitTag.findAll({where:{id:data['tagIds']}})returnSequelize.transaction(function(t){returnPost.create({name:data.name},{transaction:t}).then(function(post){returnpost.setTags(tags,{transaction:t})});}).then(function(result){//交易已提交结果是promise链返回事务回调的结果}).catch(function(err){//事务已经回滚throwthrowsanerrorthrowerr;});}//关于交易更具体的内容,可以查看Sequelize文档(虽然是全英文:))。以上仅供您参考。如果大家对belongsToMany的创建、更新、查询有更好的建议,欢迎留言。我也在探索。
