关于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 相关文章推荐
eval与window.eval的差别分析
Mar 17 Javascript
Extjs 3.3切换tab隐藏相应工具栏出现空白解决
Apr 02 Javascript
javascript的parseFloat()方法精度问题探讨
Nov 26 Javascript
js判断url是否有效的两种方法
Mar 04 Javascript
javascript的解析执行顺序在各个浏览器中的不同
Mar 17 Javascript
wangEditor编辑器失去焦点后仍然可以在原位置插入图片分析
May 06 Javascript
BootStrap使用popover插件实现鼠标经过显示并保持显示框
Jun 23 Javascript
vue 项目如何引入微信sdk接口的方法
Dec 18 Javascript
Echarts之悬浮框中的数据排序问题
Nov 08 Javascript
JS中数据结构之栈
Jan 01 Javascript
Node.js Event Loop各阶段讲解
Mar 08 Javascript
小程序实现录音上传功能
Nov 22 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获取百度收录、百度热词及百度快照的方法
2015/04/02 PHP
从新浪弄下来的全屏广告代码 与使用说明
2007/03/15 Javascript
在页面上点击任一链接时触发一个事件的代码
2007/04/07 Javascript
jQuery 处理网页内容的实现代码
2010/02/15 Javascript
ExtJS 下拉多选框lovcombo
2010/05/19 Javascript
js自动生成的元素与页面原有元素发生堆叠的解决方法
2014/09/04 Javascript
跟我学习javascript的隐式强制转换
2015/11/16 Javascript
JavaScript中 ES6 generator数据类型详解
2016/08/11 Javascript
微信小程序 教程之事件
2016/10/18 Javascript
JavaScript无操作后屏保功能的实现方法
2017/07/04 Javascript
SpringMVC简单整合Angular2的示例
2017/07/31 Javascript
vue强制刷新组件的方法示例
2019/02/28 Javascript
Node.js 多线程完全指南总结
2019/03/27 Javascript
layui表单验证select下拉框实现验证的方法
2019/09/05 Javascript
解决包含在label标签下的checkbox在ie8及以下版本点击事件无效果兼容的问题
2019/10/27 Javascript
JavaScript实现多文件下载方法解析
2020/08/07 Javascript
webstorm建立vue-cli脚手架的傻瓜式教程
2020/09/22 Javascript
vue实现可移动的悬浮按钮
2021/03/04 Vue.js
Python中的yield浅析
2014/06/16 Python
Python中使用socket发送HTTP请求数据接收不完整问题解决方法
2015/02/04 Python
Python标准库defaultdict模块使用示例
2015/04/28 Python
Python正则表达式使用范例分享
2016/12/04 Python
Python简单生成随机数的方法示例
2018/03/31 Python
Python判断有效的数独算法示例
2019/02/23 Python
python ChainMap 合并字典的实现步骤
2019/06/11 Python
Python 迭代,for...in遍历,迭代原理与应用示例
2019/10/12 Python
python分布式计算dispy的使用详解
2019/12/22 Python
Python使用urlretrieve实现直接远程下载图片的示例代码
2020/08/17 Python
雅虎笔试题(字符串操作)
2015/03/24 面试题
个人工作主要事迹
2014/05/08 职场文书
分公司任命书
2014/06/06 职场文书
毕业生自荐信范文
2015/03/05 职场文书
团委工作总结2015
2015/04/02 职场文书
小王子读书笔记
2015/06/29 职场文书
Nginx本地目录映射实现代码实例
2021/03/31 Servers
PostgreSQL并行计算算法及参数强制并行度设置方法
2022/04/06 PostgreSQL