关于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 相关文章推荐
JavaScript DOM学习第八章 表单错误提示
Feb 19 Javascript
jQuery如何使用自动触发事件trigger
Nov 29 Javascript
js实现简单的碰壁反弹效果
Aug 30 Javascript
前端实现文件的断点续传(前端文件提交+后端PHP文件接收)
Nov 04 Javascript
jquery实现文字单行横移或翻转(上下、左右跳转)
Jan 08 Javascript
微信小程序 跳转传参数与传对象详解及实例代码
Mar 14 Javascript
js读取本地文件的实例
Dec 22 Javascript
webpack 打包压缩js和css的方法示例
Mar 20 Javascript
JavaScript EventEmitter 背后的秘密 完整版
Mar 29 Javascript
Vue表单类的父子组件数据传递示例
May 03 Javascript
javascript数组的定义及操作实例
Nov 10 Javascript
ckeditor一键排版功能实现方法分析
Feb 06 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
函数中使用require_once问题深入探讨 优雅的配置文件定义方法推荐
2014/07/02 PHP
详解PHP中websocket的使用方法
2016/09/15 PHP
从阿里妈妈发现的几个不错的表单验证函数
2007/09/21 Javascript
利用JS重写Cognos右键菜单的实现代码
2010/04/11 Javascript
JQuery自定义事件的应用 JQuery最佳实践
2010/08/01 Javascript
div当滚动到页面顶部的时候固定在顶部实例代码
2013/05/27 Javascript
jquery实现弹出层遮罩效果的简单实例
2014/03/03 Javascript
jQuery实现统计输入文字个数的方法
2015/03/11 Javascript
javascript关于运动的各种问题经典总结
2015/04/27 Javascript
js实现的四级左侧网站分类菜单实例
2015/05/06 Javascript
javascript实现计时器的简单方法
2016/02/21 Javascript
JavaScript易错知识点整理
2016/12/05 Javascript
Angular.JS内置服务$http对数据库的增删改使用教程
2017/05/07 Javascript
在axios中使用params传参的时候传入数组的方法
2018/09/25 Javascript
详解JavaScript中关于this指向的4种情况
2019/04/18 Javascript
jQuery实现手风琴效果(蒙版)
2020/01/11 jQuery
详解Vue3中对VDOM的改进
2020/04/23 Javascript
[23:18]Spirit vs Liquid Supermajor小组赛A组 BO3 第二场 6.2
2018/06/03 DOTA
python中引用与复制用法实例分析
2015/06/04 Python
Python实现新浪博客备份的方法
2016/04/27 Python
python函数式编程学习之yield表达式形式详解
2018/03/25 Python
详谈python3中用for循环删除列表中元素的坑
2018/04/19 Python
Python使用urlretrieve实现直接远程下载图片的示例代码
2020/08/17 Python
Python Selenium实现无可视化界面过程解析
2020/08/25 Python
iframe跨域的几种常用方法
2019/11/11 HTML / CSS
bonprix匈牙利:女士、男士和儿童服装
2019/07/19 全球购物
日本化妆品植村秀俄罗斯官方网站:Shu Uemura俄罗斯
2020/02/01 全球购物
税务专业毕业生自荐信
2013/11/10 职场文书
质量工程师岗位职责
2013/11/16 职场文书
优秀毕业生推荐信范文
2014/03/07 职场文书
事业单位个人总结
2015/02/12 职场文书
商务信函英语问候语
2015/11/10 职场文书
创业计划书之家教托管
2019/09/25 职场文书
为什么在foreach循环中JAVA集合不能添加或删除元素
2021/06/11 Java/Android
golang 语言中错误处理机制
2021/08/30 Golang
redis调用二维码时的不断刷新排查分析
2022/04/01 Redis