关于Sequelize连接查询时inlude中model和association的区别详解


Posted in Javascript onFebruary 27, 2017

前言

大家都知道在使用Sequelize进行关系模型(表)间连接查询时,我们会通过model/as来指定已存在关联关系的连接查询模型,或是通过association来直接指定连接查询模型关系。那么,两者各应该在什么场景下使用呢?

一、 示例准备

模型定义

首先,定义User和Company两个模型:

'use strict'

const Sequelize = require('sequelize');

// 创建 sequelize 实例
const sequelize = new Sequelize('db1', 'root', '111111', {logging: console.log});

// 定义User模型
var User = sequelize.define('user', {
 id:{type: Sequelize.BIGINT(11), autoIncrement:true, primaryKey : true, unique : true},
 name: { type: Sequelize.STRING, comment:'姓名' },
 sex: { type: Sequelize.INTEGER, allowNull: false, defaultValue: 0, comment:'性别' },
 companyId: { type: Sequelize.BIGINT(11), field: 'company_id', allowNull: false, comment:'所属公司' },
 isManager: { type: Sequelize.BOOLEAN, field: 'is_manager', allowNull: false, defaultValue: false, comment:'是否管理员'}
}, 
{ charset: 'utf8',
 collate: 'utf8_general_ci'});

// 定义Company模型
var Company = sequelize.define('company', {
 id:{ type:Sequelize.BIGINT(11), autoIncrement:true, primaryKey : true, unique : true},
 name: { type: Sequelize.STRING, comment:'公司名称' }
}, 
{ charset: 'utf8',
 collate: 'utf8_general_ci'});

// 定义User-Company关联关系
User.belongsTo(Company, {foreignKey:'companyId'});

// sequelize.sync({force:true}).then(() => {
// process.exit();
// });

如上所示,我们定义了User和Company两个模型,并通过belongsTo指定了User-Company之间为1:1关系。

插入数据

接下来基于刚定义的关系模型插入一些测试数据:

Company.create({name:'某公司'}).then((result) => {
 return Promise.all([
 User.create({name:'何民三', sex:1, companyId:result.id, isManager: true}),
 User.create({name:'张老二', sex:1, companyId:result.id})
 ])
}).then((result) => {
 console.log('done');
}).catch((err) => {
 console.error(err);
});

二、使用model/as

在进行连接查询时,如果已经定义模型间的关联关系。就可以在inlude查询选项中,通过'model'属性指定要连接查询的模型,还可以通过'as'属性指定别名。

如,从User模型中查询一个用户,并查询该用户所在的公司信息:

var include = [{
 model: Company,
 as: 'company'
}];
User.findOne({include:include}).then((result) => {
 console.log(result.name + ' 是 '+result.company.name+' 的员工');
}).catch((err) => {
 console.error(err);
});

查询结果如下:

何民三 是 某公司 的员工

三、使用association

连接查询时,如果要连接查询的两个模型间事先没有定义连接关系,或者要使用定义之外的连接关系。这时,可以通过association来定义或重新定义模型关系。

如,查询Company模型中的任意一个公司,并查询该公司的管理员:

var include = [{
 association: Company.hasOne(User, {foreignKey:'companyId', as:'manager'}),
 where: {isManager:true}
}]

Company.findOne({include:include}).then((result) => {
 console.log(result.name +' 的管理员是 ' +result.manager.name);
}).catch((err) => {
 console.error(err);
});

由于Company-User之间并没有事先定义模型关系,因此需要在inlude选项中指定连接查询时所要使用的关联关系。

查询结果如下:

某公司 的管理员是 何民三

association除了用于指定之前没有定义的模型关系,还可以用于重新用于定义模型关系。如,假设我们通过hasMany事先定义了Company-User之间存在1:N的关系。这种关系适用于查询公司下的所有员工。而上例中,我们需要通过1:1关系来查公司的管理员,因此,这时可以通过association重新定义模型关系。

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
DIY jquery plugin - tabs标签切换实现代码
Dec 11 Javascript
JavaScript中的稀疏数组与密集数组[译]
Sep 17 Javascript
js(jQuery)获取时间的方法及常用时间类搜集
Oct 23 Javascript
cookie中的path与domain属性详解
Dec 18 Javascript
浅谈JavaScript function函数种类
Dec 29 Javascript
使用jQuery实现动态添加小广告
Jul 11 jQuery
js es6系列教程 - 新的类语法实战选项卡(详解)
Sep 02 Javascript
Vue添加请求拦截器及vue-resource 拦截器使用
Nov 23 Javascript
vue项目实战总结篇
Feb 11 Javascript
Javascript读写cookie的实例源码
Mar 16 Javascript
vue移动端写的拖拽功能示例代码
Sep 09 Javascript
JS前端可扩展的低代码UI框架Sunmao使用详解
Jul 23 Javascript
详解Javascript几种跨域方式总结
Feb 27 #Javascript
JavaScript与JQUERY获取元素的宽、高和位置
Feb 26 #Javascript
JavaScript无阻塞加载和defer、async详解
Feb 26 #Javascript
浅谈JavaScript中的apply/call/bind和this的使用
Feb 26 #Javascript
JavaScript中Promise的使用详解
Feb 26 #Javascript
setTimeout函数的神奇使用
Feb 26 #Javascript
node.js入门学习之url模块
Feb 25 #Javascript
You might like
PHP学习笔记之一
2011/01/17 PHP
PHP中使用xmlreader读取xml数据示例
2014/12/29 PHP
Opcache导致php-fpm崩溃nginx返回502
2015/03/02 PHP
PHP之正则表达式捕获组与非捕获组(详解)
2015/07/29 PHP
PHP面向对象五大原则之里氏替换原则(LSP)详解
2018/04/08 PHP
php使用redis的几种常见操作方式和用法示例
2020/02/20 PHP
JavaScript中使用document.write向页面输出内容实例
2014/10/16 Javascript
jQuery的内容过滤选择器学习教程
2016/04/18 Javascript
全国省市二级联动下拉菜单 js版
2016/05/10 Javascript
less简单入门(CSS 预处理语言)
2017/03/08 Javascript
javascript帧动画(实例讲解)
2017/09/02 Javascript
详解extract-text-webpack-plugin 的使用及安装
2018/06/12 Javascript
JavaScript实现简单的隐藏式侧边栏功能示例
2018/08/31 Javascript
Bootstarp在pycharm中的安装及简单的使用方法
2019/04/19 Javascript
Vue实现表格批量审核功能实例代码
2019/05/28 Javascript
vue 实现路由跳转时更改页面title
2019/11/05 Javascript
[03:55]TI9战队采访——TNC Predator
2019/08/22 DOTA
python发送伪造的arp请求
2014/01/09 Python
Django中URLconf和include()的协同工作方法
2015/07/20 Python
Python简单计算数组元素平均值的方法示例
2017/12/26 Python
python2.7无法使用pip的解决方法(安装easy_install)
2018/04/03 Python
Python函数参数操作详解
2018/08/03 Python
使用python Fabric动态修改远程机器hosts的方法
2018/10/26 Python
详解如何管理多个Python版本和虚拟环境
2019/05/10 Python
Python使用线程来接收串口数据的示例
2019/07/02 Python
Django框架下静态模板的继承操作示例
2019/11/08 Python
Python迭代器协议及for循环工作机制详解
2020/07/14 Python
python -v 报错问题的解决方法
2020/09/15 Python
瑞士国际航空官网:SWISS
2016/07/21 全球购物
印度尼西亚值得信赖的第一家网店:Bhinneka
2018/07/16 全球购物
简单说下OSPF的操作过程
2014/08/13 面试题
Linux不知道文件后缀名怎么判断文件类型
2012/04/26 面试题
广告学专业毕业生自荐信
2013/09/24 职场文书
电大自我鉴定范文
2013/10/01 职场文书
代理人委托书
2014/09/16 职场文书
Python中的min及返回最小值索引的操作
2021/05/10 Python