审核中~
溜忙之道
首页
溜忙手册
offer之道
项目Git
写文章
登录
·
注册
登录
没有账号,去注册
注册
已有账号,去登录
博客
Node.js Sequelize 模型(表)之间的关联及关系模型的操作(二)
南易_站长
阅读量:8401
关注
Node.js Sequelize 模型(表)之间的关联及关系模型的操作(二)
### 2. 关系模型(表)的操作(CRUD) 为了方便操作,本示例以一个[](http://itbilu.com/nodejs/npm/EJUJrGVsg.html)Web应用的方式提供,每个操作都做为一个单独的路由,实现详细请查看[routes/index.js](https://github.com/itbilu/sequlize_model_relation_demo/blob/master/routes/index.js)文件。运行项目后,在浏览器输入相应路径即可查看效果。 #### 2.1 插入数据 **单独插入数据** 为`User`和`Role`添加数据: ``` Promise.all([ User.create({username:'itbilu', password:'itbilu.com'}), Role.create({roleName:'管理员'}) ]).then(function(results){ res.set('Content-Type', 'text/html; charset=utf-8') res.end('创建成功:'+JSON.stringify({user:results[0].dataValues, role:results[1].dataValues})); }).catch(next); ``` 运行项目,并访问以下路径可查看执行效果: ``` http://localhost:3000/ ``` 控制台打印,执行的SQL类似如下: ``` Executing (default): INSERT INTO `user` (`id`,`username`,`password`,`active`,`created_at`,`updated_at`) VALUES (DEFAULT,'itbilu','itbilu.com',true,'2016-07-07 10:00:11','2016-07-07 10:00:11'); Executing (default): INSERT INTO `role` (`id`,`role_name`) VALUES (DEFAULT,'管理员'); ``` **关联模型插入数据** 被关联的“目标模型”可以调用其自身的`create()`等方法插入数据,可以通过“源模型”的[模型实例](http://itbilu.com/nodejs/npm/N1sdaHTzb.html)中*设置器方法*插入数据。 **注意:**定义模型的关联关系后,对于`1:1`或`1:N`关系模型,目标模型会做为源模型的一个实例属性提供,同时会相应的*设置器方法*源模型实例中;而对于`N:M`关系模型,源模型及目标模型会做为彼些的实例属性提供,并为双方相应的*设置器方法*。 如:通过`User`实例,`UserCheckin`中插入数据: ``` User.create({username:'itbilu', password:'itbilu.com'}).then(function(user){ var userCheckin = UserCheckin.build({loginIp:'127.0.0.1'}); user.setUserCheckin(userCheckin); res.set('Content-Type', 'text/html; charset=utf-8'); res.end('UserCheckin 插入数据成功'); }).catch(next); ``` 访问URI: ``` http://localhost:3000/create/checkin ``` 在上面`setUserCheckin()`操作中,会执行类似以下SQL语句: ``` INSERT INTO `userCheckin` (`id`,`login_ip`,`created_at`,`updated_at`,`user_id`) VALUES (DEFAULT,'127.0.0.1','2016-07-07 11:06:23','2016-07-07 11:06:23',26); ``` 对于`N:M`关系的两个模型,如果未显式定义关系模型(关系表),就只能通过源模型实例或目标模型实例向数据库中的关系表插入数据。通过`User`及`Role`实例,向关系表插入数据: ``` Promise.all([ User.create({username:'itbilu', password:'itbilu.com'}), Role.create({roleName:'管理员'}) ]).then(function(results){ var user = results[0]; var role = results[1]; user.setUserRoles(role); // 或 // role.setUserRoles(user); res.set('Content-Type', 'text/html; charset=utf-8'); res.end('userRoles 插入数据成功'); }).catch(next); ``` 访问URI: ``` http://localhost:3000/create/userRoles ``` 会执行类似如下SQL语句: ``` INSERT INTO `userRoles` (`user_id`,`role_id`,`created_at`,`updated_at`) VALUES (41,24,'2016-07-07 11:29:11','2016-07-07 11:29:11'); ``` #### 2.2 数据查询 对于`1:1`关联关系的模型,可以在查询时通过[`include`](http://itbilu.com/nodejs/npm/V1PExztfb.html#api-findAll)指定要连接查询的模型。指定后Sequelize会自动生成连接查询语句: ``` User.findOne({include:[UserCheckin]}).then(function(user){ console.log(user); res.set('Content-Type', 'text/html; charset=utf-8'); res.end(JSON.stringify(user)); }).catch(next); ``` 访问URI: ``` http://localhost:3000/select/user ``` 生成的查询语句类型如下: ``` SELECT `User`.`id`, `User`.`username`, `User`.`password`, `User`.`active`, `User`.`created_at`, `User`.`updated_at`, `User`.`deleted_at`, `UserCheckin`.`id` AS `UserCheckin.id`, `UserCheckin`.`user_id` AS `UserCheckin.userId`, `UserCheckin`.`login_ip` AS `UserCheckin.loginIp`, `UserCheckin`.`created_at` AS `UserCheckin.created_at`, `UserCheckin`.`updated_at` AS `UserCheckin.updated_at`, `UserCheckin`.`user_id` AS `UserCheckin.user_id` FROM `user` AS `User` LEFT OUTER JOIN `userCheckin` AS `UserCheckin` ON `User`.`id` = `UserCheckin`.`user_id` WHERE `User`.`deleted_at` IS NULL LIMIT 1; ``` 而`1:N`或`N:M`关系的模型,可以通过调用源模型实例的访问器方法查询目标模型。如,查询`UserAddress`: ``` User.findOne().then(function(user){ user.getAddress(); res.set('Content-Type', 'text/html; charset=utf-8'); res.end(JSON.stringify(user)); }).catch(next); ``` 访问URI: ``` http://localhost:3000/select/userAddress ``` 调用`user.getAddress()`时,会执行类似如下语句: ``` SELECT `id`, `user_id` AS `userId`, `consignee`, `address`, `zip_code` AS `zipCode`, `tel`, `user_id` FROM `userAddress` AS `UserAddress` WHERE `UserAddress`.`user_id` = 1; ``` #### 2.3 数据更新 访问器方法同样可以用于关系模型的更新,使用设置器设置属性时,设置器方法首先会通过`isNewRecord`特性判断是否是新记录,从而进行插入数据或更新数据。 如,通过`User`实例更新`UserCheckin`: ``` User.findOne({include:[UserCheckin]}).then(function(user){ var userCheckin = UserCheckin.build({userId:user.id, loginIp:'192.168.0.1'}); user.setUserCheckin(userCheckin); res.set('Content-Type', 'text/html; charset=utf-8'); res.end(JSON.stringify(user)); }).catch(next); ``` 访问URI: ``` http://localhost:3000/delete/user ``` 会生成类似如下两条SQL语句: ``` UPDATE `userCheckin` SET `user_id`=NULL,`updated_at`='2016-07-07 14:12:07' WHERE `id` = 17; INSERT INTO `userCheckin` (`id`,`user_id`,`login_ip`,`created_at`,`updated_at`) VALUES (DEFAULT,1,'192.168.0.1','2016-07-07 14:12:07','2016-07-07 14:12:07'); ``` #### 2.4 数据删除 对于逻辑删除的模(`paranoid: true`),删除时会向表中更新一个`deleted_at`时间戳。 删除`User`: ``` User.destroy({where:{id:2}}).then(function(result){ res.set('Content-Type', 'text/html; charset=utf-8'); res.end('删除完成'); }).catch(next); // 使用模型实例删除 // User.findOne().then(function(user){ // user.destroy(); // res.set('Content-Type', 'text/html; charset=utf-8'); // res.end('删除完成'); // }).catch(next); ``` 访问URI: ``` http://localhost:3000/delete/user ``` 逻辑删除相当于一个更新操作。生成的SQL语句类型如下: ``` UPDATE `user` SET `deleted_at`='2016-07-07 14:46:01' WHERE `deleted_at` IS NULL AND `id` = 2; ``` 转载自:https://itbilu.com/nodejs/npm/EJarwPD8W.html
评论
表情
发送
0
评论