关于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 相关文章推荐
基于JQuery的Select选择框的华丽变身
Aug 23 Javascript
jquery 层次选择器siblings与nextAll的区别介绍
Aug 02 Javascript
Javascript 中创建自定义对象的方法汇总
Dec 04 Javascript
jQuery使用each方法与for语句遍历数组示例
Jun 16 Javascript
微信小程序 新建登录页并实现tabBar隐藏
Jun 13 Javascript
利用JavaScript实现栈的数据结构示例代码
Aug 02 Javascript
JS中实现隐藏部分姓名或者电话号码的代码
Jul 17 Javascript
详解Angularjs 自定义指令中的数据绑定
Jul 19 Javascript
webstorm+vue初始化项目的方法
Oct 18 Javascript
node全局变量__dirname与__filename的区别
Jan 14 Javascript
详解Vue依赖收集引发的问题
Apr 22 Javascript
layui-table获得当前行的上/下一行数据的例子
Sep 24 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
DC宇宙的第一个英雄,堪称动漫史鼻祖,如今成为美国文化的象征
2020/04/09 欧美动漫
浅谈web上存漏洞及原理分析、防范方法(文件名检测漏洞)
2013/06/29 PHP
PHP程序员基本要求和必备技能
2014/05/09 PHP
PHP获取用户访问IP地址的5种方法
2016/05/16 PHP
php中类和对象:静态属性、静态方法
2017/04/09 PHP
通过源码解析Laravel的依赖注入
2018/01/22 PHP
PHP程序员学习使用Swoole的理由
2018/06/24 PHP
jQuery源码分析之Event事件分析
2010/06/07 Javascript
js中页面的重新加载(当前页面/上级页面)及frame或iframe元素引用介绍
2013/01/24 Javascript
node.js中的fs.fchownSync方法使用说明
2014/12/16 Javascript
详解jQuery中基本的动画方法
2016/12/14 Javascript
深入了解JavaScript的逻辑运算符(与、或)
2016/12/20 Javascript
微信小程序的动画效果详解
2017/01/18 Javascript
javascript设计模式之单体模式学习笔记
2017/02/15 Javascript
不得不看之JavaScript构造函数及new运算符
2017/08/21 Javascript
你应该知道的几类npm依赖包管理详解
2017/10/06 Javascript
Angular5中调用第三方库及jQuery的添加的方法
2018/06/07 jQuery
微信小程序之判断页面滚动方向的示例代码
2018/08/30 Javascript
原生JS实现轮播图效果
2018/10/12 Javascript
jQuery实现获取当前鼠标位置并输出功能示例
2019/01/05 jQuery
JS实现提示框跟随鼠标移动
2019/08/27 Javascript
JavaScript鼠标拖拽事件详解
2020/04/03 Javascript
JS中多层次排序算法的实现代码
2021/01/06 Javascript
[02:51]DOTA2英雄基础教程 艾欧
2014/01/13 DOTA
[01:05:12]2014 DOTA2国际邀请赛中国区预选赛 TongFu VS CIS-GAME
2014/05/21 DOTA
python通过pil模块将raw图片转换成png图片的方法
2015/03/16 Python
python调用fortran模块
2016/04/08 Python
python3+PyQt5实现支持多线程的页面索引器应用程序
2018/04/20 Python
python 实现得到当前时间偏移day天后的日期方法
2018/12/31 Python
Python FTP文件定时自动下载实现过程解析
2019/11/12 Python
Python操作MySQL数据库的示例代码
2020/07/13 Python
python3.7调试的实例方法
2020/07/21 Python
公司担保书格式范文
2014/05/12 职场文书
2015年技术工作总结范文
2015/04/20 职场文书
《堡垒之夜》联动《刺客信条》 4月7日正式上线
2022/04/06 其他游戏
Python实现Matplotlib,Seaborn动态数据图
2022/05/06 Python