Koa2使用sequelize操作Mysql(一) sequelize

2023-10-09 20:10

本文主要是介绍Koa2使用sequelize操作Mysql(一) sequelize,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

Sequelize是用于Postgres,MySQL,MariaDB,SQLite和Microsoft SQL Server的基于promise的Node.js ORM工具。它具有可靠的事务支持,关系,急切和延迟加载,读取复制等功能。

Sequelize遵循语义版本控制,并支持Node v10及更高版本。

sequelize的npm地址:https://www.npmjs.com/package/sequelize

安装:

npm i sequelize

其要和一个数据库结合使用,这里我们选择mysql, 而在我们的koa2工程中, 我们使用mysql2库来操作数据库

npm i mysql2

一. 连接MySQL数据库

  1. 首先导入模块
const { Sequelize } = require('sequelize');
  1. 用导入的Sequelize 实例化一个sequelize对象:
const sequelize = new Sequelize('db1', 'root', 'xxxxx', {host: 'localhost', //数据库地址dialect: 'mysql', //指定连接的数据库类型pool: {max: 5, //连接池最大连接数量min: 0, //最小连接数量idle: 10000, //如果一个线程 10秒内么有被使用过的话,就释放},
})

这样就完成了数据库链接了
我们可以测试一下:
sequelize对象提供了一个authenticate方法,可以测试数据库链接https://sequelize.org/master/class/lib/sequelize.js~Sequelize.html#instance-method-authenticate

我们可以看到它return 一个promise, 所以我们应该在一个async方法里处理这个promise

例如: 我们在index.js里写一个访问127.0.0.1就告诉我们数据库连接是否成功的API,可以:

const router = require('koa-router')()
const { Sequelize } = require('sequelize');const sequelize = new Sequelize('db1', 'root', 'xxxxxx', {host: 'localhost', //数据库地址dialect: 'mysql', //指定连接的数据库类型pool: {max: 5, //连接池最大连接数量min: 0, //最小连接数量idle: 10000, //如果一个线程 10秒内么有被使用过的话,就释放},
})router.get('/', async (ctx, next) => {let str1str1 = await sequelize.authenticate().then(() => {return '连接数据库成功'}).catch(err => {return '连接数据库失败' + err});ctx.body = str1
})module.exports = router

二. 创建模型:(获取表)

https://sequelize.org/master/manual/model-basics.html

1. 创建模型

连接数据库成功后, 怎么使用ORM的方式把数据库用起来呢? 答: 创建模型

模型是Sequelize的本质。模型是代表数据库中的抽象。

Sequelize中的模型有一个名称。此名称不必与它在数据库中表示的表的名称相同。通常,模型具有单数名称(例如User),而表具有复数名称(例如Users),尽管这是完全可配置的。

通过创建模型,我们将MySQL中的表和模型对应起来

class Student extends Model { }//创建一个类,继承Model
Student.init({id: { type:DataTypes.INTEGER, primaryKey: true },name: DataTypes.STRING,age: DataTypes.INTEGER,score: DataTypes.FLOAT,brithday: DataTypes.DATE,
}, { sequelize, modelName: 'Student' })

除了这种声明方法,还有一种方法把一张表声明为一个model,这种方法本质上还是在调用init函数, 用哪种随你喜欢

const Student = sequelize.define('Student111', {id: { type: DataTypes.INTEGER, primaryKey: true },name: DataTypes.STRING,age: DataTypes.INTEGER,score: DataTypes.FLOAT,brithday: DataTypes.DATE,
}, {sequelize})

2. 模型同步

定义模型时,您要告诉Sequelize有关数据库中表的一些信息。但是,如果该表实际上甚至不存在于数据库中怎么办?如果存在,但具有不同的列,较少的列或任何其他差异,该怎么办?这就需要模型同步。

  • User.sync() -如果表不存在,则会创建表(如果已经存在,则不执行任何操作)
  • User.sync({ force: true }) -这将创建表,如果该表已经存在,则将其首先删除
  • User.sync({ alter: true }) -这将检查数据库中表的当前状态(它具有哪些列,它们的数据类型是什么,等等),然后在表中进行必要的更改以使其与模型匹配。
Student.sync({ alter: true })

3. 注意一个sequelize的默认行为:时间戳记

默认情况下,Sequelize使用数据类型自动将字段createdAt和添加updatedAt到每个模型中(DataTypes.DATE类型)。

这些字段也会自动进行管理-每当您使用Sequelize创建或更新内容时,这些字段都会被正确设置。该createdAt字段将包含代表创建时刻的时间戳,并且updatedAt将包含最新更新的时间戳。

注意:这是在Sequelize级别完成的(即,不使用SQL触发器完成)。使用者无需干预。

但是通过不使用Sequelize的情况下执行的查询, 将不会导致这些字段自动更新。
可以使用以下timestamps: false选项为模型禁用此行为:

sequelize.define('User', {// ... (attributes)
}, {timestamps: false
});

上面我们得到了数据库的映射对象sequelize,以及表的映射对象User, 接下来, 我们先尝试操作表

三. 创建模型实例 (表中插入数据) // 增

数据就相当于''模型类''的实例化

3.1 build方法

尽管模型是类,但是您不应new直接使用运算符来创建实例。相反,应使用build方法:

const ldy = Student.build({name:"林黛玉",age:17, score:100,brithday: new Date('2010-12-05')})console.log(ldy instanceof Student); ldy.save()

注意:build根本不与数据库通信(请注意: 它甚至不是异步的)
build完成后应该用save方法保存到数据库中

3.2 create方法

Sequelize提供了create方法将以上的build和save方法组合为一个方法:

const yyh = await Student.create({name:"杨玉环",age:25, score:95,brithday: new Date('2009-12-05')})

3.3 Sequelize提供了Model.bulkCreate方法,该方法一次就可以创建多个记录。

Model.bulkCreate与Model.create极为相似,方法接收对象数组而不是单个对象。

const captains = await Captain.bulkCreate([{ name: 'Jack Sparrow' },{ name: 'Davy Jones' }
]);

默认情况下,bulkCreate不会在要创建的每个对象上运行验证(create会验证)。要bulkCreate运行验证,您必须传递validate: true选项。但这会降低性能。

const Foo = sequelize.define('foo', {bar: {type: DataTypes.TEXT,validate: {len: [4, 6]}}
});

四. 查找模型中的数据 (查表) //查

4.1 查找模型中所有数据 findAll

相当于SELECT * FROM ...

router.get('/', async (ctx, next) => {const students = await Student.findAll();console.log(students.every(student => student instanceof Student)); // truectx.body = "All students:" + JSON.stringify(students, null, 2)
})
4.1.1 findAll指定查询的属性

相当于: SELECT foo, bar FROM ...

router.get('/', async (ctx, next) => {const students = await Student.findAll({ attributes: ['name', 'age'] });console.log(students.every(student => student instanceof Student)); // truectx.body = "All students:" + JSON.stringify(students, null, 2)
})
4.1.2 取别名

相当于: SELECT foo, bar AS baz, qux FROM ...

Model.findAll({attributes: ['foo', ['bar', 'baz'], 'qux']
});

4.2 按条件查找模型 //应用WHERE子句

4.2.1 按条件查找模型

相当于SELECT * FROM post WHERE authorId = 2

router.get('/', async (ctx, next) => {const students = await Student.findAll({where: { id: 2 }});ctx.body = "All students:" + JSON.stringify(students, null, 2)
})

如果有多个筛选条件,也是可以的

const students = await Student.findAll({where: {age: 17, score: 100}});
4.2.2 where and 条件

如果引入Op对象, 可以用and 筛选多个条件, 效果同上

const { Op } = require("sequelize");
router.get('/', async (ctx, next) => {const students = await Student.findAll({where: {[Op.and]: [{ age: 17 },{ score: 100 }]}});ctx.body = "All students:" + JSON.stringify(students, null, 2)
})
4.2.2 where or 条件

如果需要OR限定, 也应该使用Op对象,对象的列表里写的是同一个属性

const students = await Student.findAll({where: {[Op.or]: [{ age: 17 },{ age: 25 }]}});

还有一种写法,功能是一样的:

const students = await Student.findAll({where: {age: {[Op.or]: [17, 25]}}});
4.2.3 Op对象有好多种用法:
onst { Op } = require("sequelize");
Post.findAll({where: {[Op.and]: [{ a: 5 }, { b: 6 }],            // (a = 5) AND (b = 6)[Op.or]: [{ a: 5 }, { b: 6 }],             // (a = 5) OR (b = 6)someAttribute: {// Basics[Op.eq]: 3,                              // = 3[Op.ne]: 20,                             // != 20[Op.is]: null,                           // IS NULL[Op.not]: true,                          // IS NOT TRUE[Op.or]: [5, 6],                         // (someAttribute = 5) OR (someAttribute = 6)// Using dialect specific column identifiers (PG in the following example):[Op.col]: 'user.organization_id',        // = "user"."organization_id"// Number comparisons[Op.gt]: 6,                              // > 6[Op.gte]: 6,                             // >= 6[Op.lt]: 10,                             // < 10[Op.lte]: 10,                            // <= 10[Op.between]: [6, 10],                   // BETWEEN 6 AND 10[Op.notBetween]: [11, 15],               // NOT BETWEEN 11 AND 15// Other operators[Op.all]: sequelize.literal('SELECT 1'), // > ALL (SELECT 1)[Op.in]: [1, 2],                         // IN [1, 2][Op.notIn]: [1, 2],                      // NOT IN [1, 2][Op.like]: '%hat',                       // LIKE '%hat'[Op.notLike]: '%hat',                    // NOT LIKE '%hat'[Op.startsWith]: 'hat',                  // LIKE 'hat%'[Op.endsWith]: 'hat',                    // LIKE '%hat'[Op.substring]: 'hat',                   // LIKE '%hat%'[Op.iLike]: '%hat',                      // ILIKE '%hat' (case insensitive) (PG only)[Op.notILike]: '%hat',                   // NOT ILIKE '%hat'  (PG only)[Op.regexp]: '^[h|a|t]',                 // REGEXP/~ '^[h|a|t]' (MySQL/PG only)[Op.notRegexp]: '^[h|a|t]',              // NOT REGEXP/!~ '^[h|a|t]' (MySQL/PG only)[Op.iRegexp]: '^[h|a|t]',                // ~* '^[h|a|t]' (PG only)[Op.notIRegexp]: '^[h|a|t]',             // !~* '^[h|a|t]' (PG only)[Op.any]: [2, 3],                        // ANY ARRAY[2, 3]::INTEGER (PG only)// In Postgres, Op.like/Op.iLike/Op.notLike can be combined to Op.any:[Op.like]: { [Op.any]: ['cat', 'hat'] }  // LIKE ANY ARRAY['cat', 'hat']// There are more postgres-only range operators, see below}}
});
4.2.4 Op.in可以简写
const students = await Student.findAll({where: {age:  [17, 25]}});

五. 更多查询方法

1. findByPk 按主键查询

const student = await Student.findByPk(2)

2. findOne 找到第一个条目

const student = await Student.findOne({ where: { age: 17 } })

3. findOrCreate 查询或创建

findOrCreate将在表中找满足查询选项的条目, 没有则创建一个条目。

在这两种情况下,它都会返回一个实例(找到的实例或创建的实例)和一个布尔值,指示该实例是已创建还是已经存在。

const [student, created] = await Student.findOrCreate({where: { name: "范冰冰" },defaults: {age: 35, score: 100,brithday: new Date('2020-03-05')}})

不知道是不是我用的不对, 创建时会在服务器控制台报错, 但仍旧能创建成功

3. findAndCountAll

findAndCountAll方法是组合findAll和的便捷方法count。
该findAndCountAll方法返回一个具有两个属性的对象:

count -整数-符合查询条件的记录总数
rows -对象数组-获得的记录

router.get('/', async (ctx, next) => {const {count, rows} = await Student.findAndCountAll({where: {age: {[Op.lt]: 25}}})let str1 = ''rows.forEach((row) => str1 += JSON.stringify(row, null, 2))ctx.body = 'rows:\n' + str1 + '\ncount\n' + count
})

五. order排序查询

order选项采用一项或一个sequelize方法进行排序。
例如:

const students = await Student.findAll({order: ['age']})

order有好多用法:

Subtask.findAll({order: [// Will escape title and validate DESC against a list of valid direction parameters['title', 'DESC'],// Will order by max(age)sequelize.fn('max', sequelize.col('age')),// Will order by max(age) DESC[sequelize.fn('max', sequelize.col('age')), 'DESC'],// Will order by  otherfunction(`col1`, 12, 'lalala') DESC[sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'],// Will order an associated model's createdAt using the model name as the association's name.[Task, 'createdAt', 'DESC'],// Will order through an associated model's createdAt using the model names as the associations' names.[Task, Project, 'createdAt', 'DESC'],// Will order by an associated model's createdAt using the name of the association.['Task', 'createdAt', 'DESC'],// Will order by a nested associated model's createdAt using the names of the associations.['Task', 'Project', 'createdAt', 'DESC'],// Will order by an associated model's createdAt using an association object. (preferred method)[Subtask.associations.Task, 'createdAt', 'DESC'],// Will order by a nested associated model's createdAt using association objects. (preferred method)[Subtask.associations.Task, Task.associations.Project, 'createdAt', 'DESC'],// Will order by an associated model's createdAt using a simple association object.[{model: Task, as: 'Task'}, 'createdAt', 'DESC'],// Will order by a nested associated model's createdAt simple association objects.[{model: Task, as: 'Task'}, {model: Project, as: 'Project'}, 'createdAt', 'DESC']],// Will order by max age descendingorder: sequelize.literal('max(age) DESC'),// Will order by max age ascending assuming ascending is the default order when direction is omittedorder: sequelize.fn('max', sequelize.col('age')),// Will order by age ascending assuming ascending is the default order when direction is omittedorder: sequelize.col('age'),// Will order randomly based on the dialect (instead of fn('RAND') or fn('RANDOM'))order: sequelize.random()
});Foo.findOne({order: [// will return `name`['name'],// will return `username` DESC['username', 'DESC'],// will return max(`age`)sequelize.fn('max', sequelize.col('age')),// will return max(`age`) DESC[sequelize.fn('max', sequelize.col('age')), 'DESC'],// will return otherfunction(`col1`, 12, 'lalala') DESC[sequelize.fn('otherfunction', sequelize.col('col1'), 12, 'lalala'), 'DESC'],// will return otherfunction(awesomefunction(`col`)) DESC, This nesting is potentially infinite![sequelize.fn('otherfunction', sequelize.fn('awesomefunction', sequelize.col('col'))), 'DESC']]
});

六. 分组查询

const students = await Student.findAll({group: 'name'})

七. 查询的限制和分页

在limit和offset选项允许您使用限制/分页工作:

// Fetch 10 instances/rows
Project.findAll({ limit: 10 });// Skip 8 instances/rows
Project.findAll({ offset: 8 });// Skip 5 instances and fetch the 5 after that
Project.findAll({ offset: 5, limit: 5 });
通常,这些order选项与选项一起使用。

八. 更新模型中的数据(更新表中数据)

8.1. 简单的UPDATE

更新也接受where选项,就像上面的读取一样。

await Student.update({ age: 23 },{where: {name: '杨玉环'}})

九. 删除表中数据

删除也接受where选项,就像上面的读取一样。

await Student.destroy({where: {name: '杨玉环'}})

十. 使用原始SQL语句

在很多情况下执行原始SQL查询更加容易,此时可以使用sequelize.query方法。
默认情况下,该函数将返回两个参数: -一个结果数组和一个包含元数据的对象(例如,受影响的行数等), 但对于MySQL,它们将是对同一对象的两个引用。

const [results, metadata] = await sequelize.query("UPDATE users SET y = 42 WHERE x = 12");

关于原始查询:详见:https://sequelize.org/master/manual/raw-queries.html

十一. 建立表间连接

表与表之间无外乎:

一对一 belongsto
外键一对一 hasone
一对多 hasmany
多对多 belongsToMany

Banner.belongsTo(Image, {foreignKey: 'img_id',targetKey: 'id'
})

今天我们熟悉了很多sequelize的特性和方法, 基本可以掌握sequelize的用法, 下一步: 我们将对sequelize进行封装, 具体请参考下一篇文章.


http://www.taodudu.cc/news/show-7905016.html

相关文章:

  • 欢迎使用CSDN-markdown编辑器lalala
  • 2018.12.15 cnblog open lalala, 1st output.
  • 新的开始16219lalala
  • LALALA我来了
  • lalala
  • 【雕爷学编程】MicroPython手册之 OpenMV Cam pyb.delay
  • Android Camera应用开发小结
  • 视频录像循环存储
  • Windows95平台下数控系统实时控制的研究
  • vmware与Windows出现不兼容问题
  • 【pytorch】torch.mean()
  • 利用Upnp映射到外网
  • upnp解析
  • UPnP原理简介
  • 【转】UPnP基本原理介绍
  • UPnP中Control Point的基本流程
  • 路由器之UPnP协议
  • 【最优传输论文十四】2019 CVPR-Sliced Wasserstein Discrepancy for Unsupervised Domain Adaptation
  • svn不能查看提交日志log,时间显示1970,提示offline for now, Permanently offline
  • POST请求慎用301 Moved Permanently
  • 小程序 Status Code: 301 Moved Permanently (from disk cache)
  • hadoop103: Warning: Permanently added the ECDSA host key for IP address ‘192.168.6.103‘ to the list
  • Warning: Permanently added ‘github.com’ (ED25519) to the list of known hosts. git@github.com
  • #java# httpclient post请求返回301 Moved Permanently解决方案
  • 报错解决 vue使用axios请求发生301 Moved Permanently错误
  • Java基础学习:成员变量:public、protected、default、private作用域
  • 不能够自动显示结构体成员或显示错误
  • iOS成员变量、成员属性和点语法
  • PTA 英文单词排序
  • c++ 类成员函数地址。
  • 这篇关于Koa2使用sequelize操作Mysql(一) sequelize的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



    http://www.chinasem.cn/article/175263

    相关文章

    SQL中的外键约束

    外键约束用于表示两张表中的指标连接关系。外键约束的作用主要有以下三点: 1.确保子表中的某个字段(外键)只能引用父表中的有效记录2.主表中的列被删除时,子表中的关联列也会被删除3.主表中的列更新时,子表中的关联元素也会被更新 子表中的元素指向主表 以下是一个外键约束的实例展示

    基于MySQL Binlog的Elasticsearch数据同步实践

    一、为什么要做 随着马蜂窝的逐渐发展,我们的业务数据越来越多,单纯使用 MySQL 已经不能满足我们的数据查询需求,例如对于商品、订单等数据的多维度检索。 使用 Elasticsearch 存储业务数据可以很好的解决我们业务中的搜索需求。而数据进行异构存储后,随之而来的就是数据同步的问题。 二、现有方法及问题 对于数据同步,我们目前的解决方案是建立数据中间表。把需要检索的业务数据,统一放到一张M

    如何去写一手好SQL

    MySQL性能 最大数据量 抛开数据量和并发数,谈性能都是耍流氓。MySQL没有限制单表最大记录数,它取决于操作系统对文件大小的限制。 《阿里巴巴Java开发手册》提出单表行数超过500万行或者单表容量超过2GB,才推荐分库分表。性能由综合因素决定,抛开业务复杂度,影响程度依次是硬件配置、MySQL配置、数据表设计、索引优化。500万这个值仅供参考,并非铁律。 博主曾经操作过超过4亿行数据

    中文分词jieba库的使用与实景应用(一)

    知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

    使用SecondaryNameNode恢复NameNode的数据

    1)需求: NameNode进程挂了并且存储的数据也丢失了,如何恢复NameNode 此种方式恢复的数据可能存在小部分数据的丢失。 2)故障模拟 (1)kill -9 NameNode进程 [lytfly@hadoop102 current]$ kill -9 19886 (2)删除NameNode存储的数据(/opt/module/hadoop-3.1.4/data/tmp/dfs/na

    Hadoop数据压缩使用介绍

    一、压缩原则 (1)运算密集型的Job,少用压缩 (2)IO密集型的Job,多用压缩 二、压缩算法比较 三、压缩位置选择 四、压缩参数配置 1)为了支持多种压缩/解压缩算法,Hadoop引入了编码/解码器 2)要在Hadoop中启用压缩,可以配置如下参数

    Makefile简明使用教程

    文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

    性能分析之MySQL索引实战案例

    文章目录 一、前言二、准备三、MySQL索引优化四、MySQL 索引知识回顾五、总结 一、前言 在上一讲性能工具之 JProfiler 简单登录案例分析实战中已经发现SQL没有建立索引问题,本文将一起从代码层去分析为什么没有建立索引? 开源ERP项目地址:https://gitee.com/jishenghua/JSH_ERP 二、准备 打开IDEA找到登录请求资源路径位置

    使用opencv优化图片(画面变清晰)

    文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

    MySQL数据库宕机,启动不起来,教你一招搞定!

    作者介绍:老苏,10余年DBA工作运维经验,擅长Oracle、MySQL、PG、Mongodb数据库运维(如安装迁移,性能优化、故障应急处理等)公众号:老苏畅谈运维欢迎关注本人公众号,更多精彩与您分享。 MySQL数据库宕机,数据页损坏问题,启动不起来,该如何排查和解决,本文将为你说明具体的排查过程。 查看MySQL error日志 查看 MySQL error日志,排查哪个表(表空间