当前位置: 首页 > 编程笔记 >

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

宇文修文
2023-03-14
本文向大家介绍关于Sequelize连接查询时inlude中model和association的区别详解,包括了关于Sequelize连接查询时inlude中model和association的区别详解的使用技巧和注意事项,需要的朋友参考一下

前言

大家都知道在使用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重新定义模型关系。

总结

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

 类似资料:
  • 我们也可以为相关联的实体甚至是对一个集合中的全部元素指定一个别名,这时要使用关键字 join。 from Cat as cat inner join cat.mate as mate left outer join cat.kittens as kitten from Cat as cat left join cat.mate.kittens as kittens from For

  • 我是套接字IO开发的新手。我想知道以下情况: > 支持的并发打开套接字数的最大限制? 为生产而微调节点服务器时需要注意的指导原则/额外的注意事项。 socket.io确保消息传递吗?还是送了就忘了?另外,在安装时是否有节点模块可以利用此特性? 如果socket.io不支持消息传递;如何确保消息被成功发送和接收到预定的人?

  • 本文向大家介绍SQL Server中的连接查询详解,包括了SQL Server中的连接查询详解的使用技巧和注意事项,需要的朋友参考一下 在查询多个表时,我们经常会用“连接查询”。连接是关系数据库模型的主要特点,也是它区别于其它类型数据库管理系统的一个标志。 什么是连接查询呢? 概念:根据两个表或多个表的列之间的关系,从这些表中查询数据。 目的:实现多个表查询操作。 知道了连接查询的概念之后,什么时

  • 本文向大家介绍关于g++和gcc的相同点和区别详解,包括了关于g++和gcc的相同点和区别详解的使用技巧和注意事项,需要的朋友参考一下 gcc和g++的区别和联系 gcc和g++都是GNU(一个组织)的编译器。 1、对于.c后缀的文件,gcc把它当做是C程序;g++当做是C++程序; 2、对于.cpp后缀的文件,gcc和g++都会当做c++程序。 3、编译阶段,g++会调用gcc; 4、连接阶段,

  • 本文向大家介绍详解MySQL中的分组查询与连接查询语句,包括了详解MySQL中的分组查询与连接查询语句的使用技巧和注意事项,需要的朋友参考一下 分组查询 group by group by 属性名 [having 条件表达式][ with rollup] “属性名 ”指按照该字段值进行分组;“having 条件表达式 ”用来限制分组后的显示,满足条件的结果将被显示;with rollup 将会在所

  • 我有以下关于连接和TCP保持活动状态的查询: 对于TCP连接,TCP保持活动状态是强制性吗? 保持活动状态的持续时间是固定的还是可配置的? 假设“保持活动”间隔为每15秒一次,那么“保持活动”是始终每15秒发送一次,还是仅在15秒内未发送应用程序数据时才发送? 服务器(通过TCP与客户机连接)如何判断与客户机的连接是否完整?是否可以使用TCP keepalive完成?在这种情况下,是否是服务器需要