【Node.JS 数据库篇】Sequelize 的用法与mysql的关系

news2024/11/28 20:41:40

文章目录

  • 一、Sequlize是Node.JS中ORM实现
  • 二、Sequelize 执行基础的CRUD
  • 三、Sequelize 执行复杂的CRUD
    • 1. 指定字段attributes
    • 2. 触发数据库事务
    • 3. LEFT JOIN 联表关系
    • 4. INNER JOIN 联表关系
    • 5. 嵌套查询
  • 四、Sequlize常用方法和参数
    • 1. findAll
    • 2. count
    • 3. findByPk
    • 4. findOne
    • 5. findAndCountAll

一、Sequlize是Node.JS中ORM实现

在 nodejs 中,「Sequlizejs」可能是最出类拔萃的 ORM 实现。植根于 nodejs,Sequlizejs 完美支持 Promise 式调用,进一步你可以走 async/await,和业务代码紧密粘合;如果上了 ts,从模型定义带来的类型提醒能让调用更省心。

表/模型的定义
ORM 的第一步就是要建立对象到数据表的映射,在 Sequlize 里是这样的,比如我们关联一个 station 的表
数据表station的定义

CREATE TABLE `station` ( 
`id` bigint(11) unsigned NOT NULL AUTO_INCREMENT, 
`store_id` varchar(20) NOT NULL DEFAULT '', 
`name` varchar(20) NOT NULL DEFAULT '', 
`type` tinyint(4) NOT NULL DEFAULT '0', 
`status` tinyint(4) NOT NULL DEFAULT '0', 
`ip` varchar(20) NOT NULL DEFAULT '', 
`related_work_order_id` bigint(20) NOT NULL DEFAULT '0', 
`created_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 
`updated_at` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, 
`plate_no` varchar(20) NOT NULL DEFAULT '', 
PRIMARY KEY (`id`) 
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 COMMENT='工位表';

Node.JS中station模型的定义

const Model = sequlize.define('station', { 
    id: { 
        field: 'id', 
        type: Sequelize.INTEGER, 
        allowNull: false, 
        primaryKey: true, 
        autoIncrement: true, 
    }, 
    store_id: Sequelize.STRING(20), 
    name: Sequelize.STRING(20), 
    type: Sequelize.TINYINT, 
    status: Sequelize.TINYINT, 
    ip: Sequelize.STRING(20), 
    plate_no: Sequelize.STRING(20), 
    related_work_order_id: Sequelize.BIGINT, 
});

二、Sequelize 执行基础的CRUD

Sequlize对象提供丰富的API,诸如:findOne、findAll、create、upsert、aggregate、max,文档/lib/model.js~Model里面安排的明明白白。

执行一个基本的CRUD
当我执行一个简单的CRUD:Station.findAll(),Sequlize转成的SQL是这样的:

SELECT 
    `id`, 
    `store_id`, 
    `name`, 
    `type`, 
    `status`, 
    `ip`, 
    `plate_no` 
FROM 
    `station` AS `station`;

三、Sequelize 执行复杂的CRUD

1. 指定字段attributes

Station.findAll({ 
    attributes: [ 'ip' ], 
    where: { 
        status: 1, 
    }, 
order: [ 
[ 'name', 'ASC' ], 
], 
limit: 10, 
offset: 5, 
});
SELECT `ip` FROM `station` AS `station` WHERE 
`station`.`status` = 1 ORDER BY `station`.`name` ASC LIMIT 5, 10;

2. 触发数据库事务

Station.findOrCreate({ 
    where: { 
        id: 1, 
    }, 
    defaults: { 
        name: 'haha', 
    }, 
});
START TRANSACTION; 
SELECT `id`, `store_id`, `name`, `type`, `status`, `ip`, `plate_no` FROM `station` AS `station` WHERE `station`.`id` = 2; 
INSERT INTO `station` (`id`,`name`) VALUES (2,`haha`); 
COMMIT;

3. LEFT JOIN 联表关系

一对一联表查询
一对一关系可用 belongsTo、hasOne 两种方式标记

// belongsTo:
File.BelongsTo(User, {
	foreignKey:'creator_id',	// File类的creatorId属性
	targetKey:'id',				// User类的id属性
});

// hasOne:
User.HasOne(File, {
	foreignKey:'creator_id',	// File类的creatorId属性
	sourceKey:'id',				// User类的id属性
});

事实上转换后的 SQL 也是一样的::LEFT JOIN::

# File.BelongsTo(User)
SELECT `file`.`id`, `user`.`id` AS `user.id`
FROM `file` 
    LEFT JOIN `user` ON `file`.`creator_id ` = `user`.`id`
# User.HasOne(File)
SELECT `user`.`id`, `file`.`id` AS `file.id`
FROM `user`
    LEFT JOIN `file` ON `user`.`id ` = `file`.`creator_id `

操作示例

// Task.belongsTo(User)

const tasks = await Task.findAll({ include: User });
console.log(JSON.stringify(tasks, null, 2));

// 结果
[{
  "name": "A Task",
  "id": 1,
  "userId": 1,
  "user": {
    "name": "张三",
    "id": 1
  }
},
{
  "name": "B Task",
  "id": 2,
  "userId": 2,
  "user": {
    "name": "李四",
    "id": 2
  }
}]

一对多联表查询

User.HasMany(File, { 
    foreignKey: 'creator_id',   // 如果不定义这个,也会自动定义为「源模型名 + 源模型主键名」即 user_id
    sourceKey: 'id',    // 源模型的关联键,默认主键,通常省略
}
// 这里 creator_id 位于目标模型 File 上

操作示例

// User.hasMany(Task);

const users = await User.findAll({ include: Task });
console.log(JSON.stringify(users, null, 2));

// 结果
[{
  "name": "张三",
  "id": 1,
  "tasks": [{
    "name": "A Task",
    "id": 1,
    "userId": 1
  }]
}]

多对多联表查询

User.BelongsToMany(Group, { 
    through: GroupUser,     // 
    foreignKey: 'group_id', // 如果不定义这个,也会自动定义为「目标模型名 + 目标模型主键名」即 user_id
    otherKey: 'user_id',
}

在这里插入图片描述

4. INNER JOIN 联表关系

预先加载时,可以强制查询仅返回具有关联模型的记录,通过 required: true 参数将查询从默认的 OUTER JOIN 转为 INNER JOIN

// User.hasMany(Task);

User.findAll({
  include: {
    model: Task,
    required: true
  }
});

5. 嵌套查询

嵌套列的顶级 WHERE 子句, Sequelize 引用嵌套列的方法:'$nested.column$', 可以用于将 where 条件从包含的模型从 ON 条件移动到顶层的 WHERE 子句

User.findAll({
  where: {
    '$Instruments.size$': { [Op.ne]: 'small' }
  },
  include: [{
    model: Tool,
    as: 'Instruments'
  }]
});

四、Sequlize常用方法和参数

1. findAll

// 从数据库读取整个表
const user = await User.findAll()
SELECT * FROM User;

// 选择某些特定属性
const user = await User.findAll({
	attributes:['name','age']
})
SELECT name,age FROM User;

// 重命名
User.findAll({
  attributes: ['name', ['age', 'ageage'], 'hats']
})
SELECT name, age AS ageage, hats FROM User;

// 使用聚合函数
User.findAll({
  attributes: {
    include: [
      [sequelize.fn('COUNT', sequelize.col('hats')), 'n_hats']
    ]
  }
})
SELECT name, age, ..., hats, COUNT(hats) AS n_hats FROM User;

// 使用聚合函数 + 部分属性字段
User.findAll({
  attributes: [
    'name',
    [sequelize.fn('COUNT', sequelize.col('hats')), 'n_hats'],
    'age'
  ]
})
SELECT name, COUNT(hats) AS n_hats, age FROM User;

// 排除部分字段
User.findAll({
  attributes: {
    include: [
      [sequelize.fn('COUNT', sequelize.col('hats')), 'n_hats']
    ],
    exclude: ['age']
  }
})
SELECT name, ..., hats, COUNT(hats) AS n_hats FROM User;

// 使用WHERE语句,and
User.findAll({
  where: {
    name: 'Tom',
    age: 20
  }
})
SELECT * FROM User WHERE name = 'TOM' AND age = 20;

// 使用WHERE语句,or
const { Op } = require('sequelize')
User.findAll({
  where: {
    [Op.or]: [
      { name: 'Tom' },
      { age: 20' }
    ]
  }
})
SELECT * FROM User WHERE name = 'TOM' OR age = 20;

// 分页限制 :跳过5行,然后获取10行
User.findAll({ offset: 5, limit: 10 })

2. count

// 查询 age = 20 的用户数量
const total = await User.count({
  where: {
    age: 20
  }
})

3. findByPk

findByPk 方法使用提供的主键从表中仅获得一行数据:

const user = await User.findByPk(1024) // 主键的值是 1024

4. findOne

findOne 方法获得它找到的 第一行 数据:

const user = await User.findOne({ where: { name: 'Tom' } })

5. findAndCountAll

结合了 findAll 和 count 的便捷方法。具体参考:findAndCountAll。findAndCountAll 方法返回有两个属性的对象:

  • count —— 整数,符合查询条件的记录总数
  • rows —— 数组对象,获得的记录
const { count, rows } = await User.findAndCountAll({
  where: {
    name: {
      [Op.like]: 'T%'
    }
  },
  offset: 10,
  limit: 2
})
console.log(count)
console.log(rows)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/470727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【策略设计模式详解】C/Java/JS/Go/Python/TS不同语言实现

简介 策略模式(Strategy Pattern)属于行为型设计模式。将每一个算法封装到具有共同接口的独立类中,根据需要来绑定策略,使得具体实现和策略解耦。 当你想使用对象中各种不同的算法变体,使用if...else 所带来的复杂和…

增强型PID-自适应-前馈-神经网络控制研究(Matlab代码实现)

💥💥💞💞欢迎来到本博客❤️❤️💥💥 🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密,逻辑清晰,为了方便读者。 ⛳️座右铭&a…

【Linux】入门介绍

🌱博客主页:大寄一场. 🌱系列专栏:Linux 😘博客制作不易欢迎各位👍点赞⭐收藏➕关注​ 目录 前言 Linux背景介绍 1.发展史 UNIX发展的历史 Linux发展历史 2. 开源 3. 官网 4. 企业应用现状 5. 发行版…

装饰者模式

采用组合而非继承的手法,Decorator模式实现了在运行时动态扩展对象功能的能力,可以根据需要扩展功能。 Decorator类在接口上表现为is-a Component的继承关系,即Decorator类继承了Component类的所有接口。但在实现上又表现为has-a Component的…

打印流~~

文章目录 打印流PrintStreamPrintWriter追加操作输出语句的重定向 Properties使用properties把键值对信息存入到属性文件中去使用properties在文件中取键值对信息 IO框架(了解) 打印流 作用:打印流可以实现方便、高效的打印数据到文件中去。打印流一般是指&#xff…

【Linux】2.1 环境基础开发工具使用——yum

什么是yum Linux 软件包管理器——yum yum(Yellow dog Updater, Modified)是Linux下非常常用的一种包管理器. 主要应用在Fedora, RedHat, Centos等发行版上. yum 的使用 卸载: yum -y(直接卸载) remove [xxx] 查找: yum list | grep [xxx] 软件包名称:…

这才是 SpringBoot 统一登录鉴权、异常处理、数据格式 的正确姿势

本篇将要学习 Spring Boot 统一功能处理模块,这也是 AOP 的实战环节 用户登录权限的校验实现接口 HandlerInterceptor WebMvcConfigurer 异常处理使用注解 RestControllerAdvice ExceptionHandler 数据格式返回使用注解 ControllerAdvice 并且实现接口 Response…

Hive拉链表实现

拉链表 定义:用来记录历史变化,相比每天存储全量数据,可大幅减少数据冗余,可以基于历史变化,统计分析历史变化信息使用场景: 用于记录维度变化场景,记录维度变化,根据维度变化记录,统计聚合,加成生成不同时期历史指标 Hive 拉链表实现 实现原理 首次(T1: 2023-04-01) 同步业…

MATLAB-Lingo求解线性规划问题-奶制品2

奶制品的生产销售计划,给定条件不变 为了增加工厂的获利,开发了奶制品的深加工技术:用2小时和3元加工费,可将1kgA1加工成0.8kg高级奶制品B1,也可将1kgA2加工成0.75kg高级奶制品B2,每千克B1能获利44元&#…

ABI Research产业研究:ZiFiSense如何革新物流货物及运输包装追踪

“文章源自前沿科技研究机构ABI Research产业研究,重点介绍了ZETA LPWA协议开发公司纵行科技在业务发展、M-FSK调制技术以及ZETag云标签系列产品在物流货物追踪与包装管理等方面的应用分析,还分享了纵行科技ZETA技术在商业市场和生态系统方面的发展情况。…

用扩展方法来实现EventTrigger中事件的异步等待

一、什么是扩展方法? 扩展方法是一种C#语言提供的功能,允许我们向现有类型添加新的方法,而无需修改类型的源代码。扩展方法的优缺点如下: 二、它有什么优点? 1、不需要修改源类型的代码:使用扩展方法可以…

工具-Snipaste与ScreenToGif 生产力工具,对截图进行勾画操作,并可将截图贴至电脑任意界面;快捷动态截图成gif

文章目录 1、演示1.1 snipaste1.2 ScreenToGif 2、操作2.1 snipaste2.2 ScreenToGif 1、演示 1.1 snipaste 1.2 ScreenToGif 2、操作 2.1 snipaste 进入官网,可根据系统进行下载 https://zh.snipaste.com/ 傻瓜式安装成功后,电脑的右下角有个小图标&a…

兰林:科技赋能健康产业 助力乡村振兴建设

万民健康创始人 万民智养中医创始人 万民星农CEO兰林 党建引领谋发展 , 旗帜下乡促振兴 。 乡村振兴,健康先行。自党的十八大以来,国家卫健委贯彻落实“以基层为重点”的党的卫生与健康工作方针,推动医疗卫生工作重心下移、资源下…

Springboot +Flowable,通过代码绘制流程图并设置高亮

一.简介 通过代码绘制一张流程图,并设置成高亮。 首先先来看一下绘制出来的效果图,截图如下: 已经执行的节点和连线用红色标记出来,大致上就是这么一个效果。 二.怎么实现 将一个流程图绘制成图片,相关的 API 在…

倾斜摄影超大场景的三维模型的顶层合并的轻量化处理技术

倾斜摄影超大场景的三维模型的顶层合并的轻量化处理技术 倾斜摄影超大场景的三维模型的顶层合并需要进行轻量化处理,以减小数据量和提高数据的传输和展示性能。以下是几种常用的轻量化处理技术: 1、网格简化:对三角面片数量过多的模型进行网…

10个常用的软件测试工具,你不容错过

在现代软件开发中,软件测试是不可或缺的一部分。为了确保软件产品的质量和稳定性,软件测试工具成为了测试团队的得力助手。 有许多优秀的软件测试工具可以帮助测试人员在各种测试活动中提高效率和准确性。 本文将介绍10个常用的软件测试工具,…

LeetCode第141题——环形链表(Java)

题目描述: 给你一个链表的头节点 head ,判断链表中是否有环。 如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链…

多线程|基于阻塞队列和环形队列的生产者消费者模型架构

前言 那么这里博主先安利一下一些干货满满的专栏啦! Linux专栏https://blog.csdn.net/yu_cblog/category_11786077.html?spm1001.2014.3001.5482操作系统专栏https://blog.csdn.net/yu_cblog/category_12165502.html?spm1001.2014.3001.5482手撕数据结构https:/…

办公软件中可以使用chatGPT吗?

随着ONLYOFFICE新品协作空间的发布,有很多朋友已经开始在工作区或桌面版用上chatGPT的朋友担心,在协作空间是否也可以正常使用chatGPT,我可以很负责的告诉大家,完全可以正常使用。 什么是ONLYOFFICE协作空间? 简言之&…

Java8新特性--Lambda表达式

一、简述 Lambda 表达式,也可称为闭包,它 允许把函数作为一个方法的参数 (函 数作为参数传递进方法中) Lambda 简化了匿名内部类的形式, 可以达到同样的效果,匿名内部类在 编译之后会创建一个新的匿名内部类 出来,而 L…