## 使用基于ORM架构的sequelize操纵数据库

### 1、技术背景

```
Sequelize是一个基于promise的关系型数据库ORM框架,*********************
技术文档
https://blog.csdn.net/lisemi/article/details/102941626----完整api
https://itbilu.com/nodejs/npm/VkYIaRPz-.html#induction-install----基础教程
https://itbilu.com/nodejs/npm/EJarwPD8W.html-----api
https://segmentfault.com/a/1190000017320533----操作多对多表关联
```

### 2、安装

```
$ npm install --save sequelize
# 还需要安装以下之一:
$ npm install --save pg pg-hstore // postgreSql
$ npm install --save mysql // mysql 或 mariadb
$ npm install --save sqlite3
$ npm install --save tedious // MSSQL
```

### 3、数据类型

```
Sequelize 中 Model 的数据类型对应MySQL中的数据类型
Sequelize.STRING // VARCHAR(255) 类型:字符串 最大值: 65535个字符
Sequelize.STRING(1234) // VARCHAR(1234) 类型:变长 最大值: 65535个字符
Sequelize.TEXT // TEXT 类型:字符串 最大值:65535个字符
Sequelize.TEXT('tiny') // TINYTEXT 类型:字符串 最大值:255个字符
Sequelize.INTEGER // INTEGER 类型:整型 最大值:范围(-2147483648~2147483647)
Sequelize.BIGINT // BIGINT 类型:整型 最大值:范围(+-9.22*10的18次方)
Sequelize.BIGINT(11) // BIGINT(11) 类型:整型 最大值:范围(+-9.22*10的18次方)
Sequelize.FLOAT // FLOAT 类型:单精度浮点型 8位精度(4字节)
Sequelize.FLOAT(11) // FLOAT(11) 类型:单精度浮点型 8位精度(4字节)
Sequelize.FLOAT(11, 12) // FLOAT(11,12) 类型:精度浮点型 8位精度(4字节) m总个数,d小数位
Sequelize.DOUBLE // DOUBLE 类型:双精度浮点型 16位精度(8字节)
Sequelize.DOUBLE(11) // DOUBLE(11) 类型:双精度浮点型 16位精度(8字节)
Sequelize.DOUBLE(11, 12) // DOUBLE(11,12) 类型:双精度浮点型 16位精度(8字节) m总个数,d小数位
Sequelize.DECIMAL // DECIMAL 类型:定点数型
Sequelize.DECIMAL(10, 2) // DECIMAL(10,2) 类型:定点数型 参数m<65 是总个数,d<30且 d<m 是小数位
Sequelize.DATE // DATETIME 类型:日期时间类型 范例:'2009-05-12 02:31:44'
Sequelize.DATE(6) // DATETIME(6)
Sequelize.DATEONLY // DATE without time.
Sequelize.BOOLEAN // TINYINT(1) 类型:整型 范围(-128~127)
Sequelize.ENUM('value 1', 'value 2') // ENUM 类型:枚举
Sequelize.BLOB // BLOB 类型:二进制数据
Sequelize.BLOB('tiny') // TINYBLOB 类型:二进制数据
```

### 3、建立连接

`Sequelize`会在初始化时设置一个连接池,这样你应该为每个数据库创建一个实例:

```
先引入,然后指向Sequelize构造函数,然后new实例化连接数据库
let Sequelize=require('sequelize')
var sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: 'mysql'|'mariadb'|'sqlite'|'postgres'|'mssql',

pool: {
max: 5,
min: 0,
idle: 10000
},

// 仅 SQLite 适用
storage: 'path/to/database.sqlite'
});

// 或者可以简单的使用一个连接 uri
var sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname');
```

### 3、 `model`定义

`model`定义格式为`sequelize.define('name', {attributes}, {options})`:

```
const Projects_cates = sequelize.define("projects_cates", {
project_id: Sequelize.STRING,
cate_id: Sequelize.STRING,
}, {
// freezeTabelName 为 true 时不会在库中映射表时增加复数表名
// 该选项为 true 时,user 在映射时映射成 user,而为 false 时会映射成users
freezeTableName: true
})

User.sync({force: true}).then(function () {
// 已创建数据表
然后写入表数据
return User.create({
firstName: 'John',
lastName: 'Hancock'
});
});
然后执行同步数据表 User改为sequelize,是全部执行同步
一次同步所有模型
可以使用sequelize.sync()方法来同步所有模型,而不是调用每个模型的sync()方法。
```

### 5、sequelize-nodejs方法

#### 5.1、执行多个方法

```
Promise.all([
db.Project_list.create({
name: '全功能APP UI KITS'
}),
db.Project_cate.create({
name: '全部11'
})
]).then(async (results)=>{
console.log('插入数据--------');
}).catch();
results------>是返回的对象,里面包含很多执行函数
```

#### 5.2、插入数据

##### `create()` - 插入单条数据

```
create(values, [options]) -> Promise.<Instance>
```

构建一个新的模型实例,并进行保存。与`build()`方法不同的是,此方法除创建新实例外,还会将其保存到对应数据库表中。

**参数**

| 名称 | 类型 | 说明 |
| ---------------------------- | ----------- | ------------------------------------ |
| values | Object | |
| [options] | Object | |
| [options.raw=false] | Boolean | 设置为`true`时,值会忽略字段和虚拟设置器 |
| [options.isNewRecord=true] | Boolean | |
| [options.fields] | Array | 如果设置后,只有列表中区别的列才会进行保存 |
| [options.include] | Array | 用于构建`prefetched/included`模型,参见 `set` |
| [options.onDuplicate] | String | |
| [options.transaction] | Transaction | 在事务中执行查询 |
| [options.logging=false] | Function | 一个用于打印查询时所执行sql的函数 |
| [options.searchPath=DEFAULT] | String | 指定schema的 search_path (仅 Postgres) |
| [options.benchmark=false] | Boolean | 当打印SQL日志时同时输出查询执行时间(毫秒) |

##### `bulkCreate()` - 创建多条记录

```
model.bulkCreate([
{
name: '全部',
btn_icon: 'fa fa-server fa-lg',
},{
name: 'PC端',
btn_icon: 'fa fa-television fa-lg',
}
])

```

批量创建并保存多个实例。

处理成功后,会在回调函数中返回一个包含多个实例的数组。

**参数**

| 名称 | 类型 | 说明 |
| -------------------------------- | ----------- | ------------------------------------- |
| records | Array | 要创建实例的对象(键/值 对)列表 |
| [options] | Object | |
| [options.fields] | Array | 要插入的字段。默认全部 |
| [options.validate=true] | Boolean | 插入每条记录前进行验证 |
| [options.hooks=true] | Boolean | 在执行前/后创建钩子 |
| [options.individualHooks=false] | Boolean | 在执行前/后为每个实例创建钩子 |
| [options.ignoreDuplicates=false] | Boolean | 忽略重复主键(Postgres不支持) |
| [options.updateOnDuplicate] | Array | 如果行键已存在是否更新(mysql & mariadb支持). 默认为更新 |
| [options.transaction] | Transaction | 在事务中执行查询 |

##### `findCreateFind()` - 查找或创建

```
findCreateFind(options) -> Promise.<Instance, created>
```

效率更高的`findOrCreate`,不会在事务中执行。首先会尝试进行查询,如果为空则尝试创建,如果是唯一约束则尝试再次查找。

**参数**

| 名称 | 类型 | 说明 |
| --------------------- | ----------- | ----------- |
| options | Object | |
| options.where | Object | 查询属性 |
| [options.defaults] | Object | 用于创建新实例的默认值 |
| [options.transaction] | Transaction | 在事务中执行查询 |

#### 5.3、查询数据

##### findAll()` - 查询多条数据

<https://itbilu.com/nodejs/npm/V1PExztfb.html#api-findAll>

```
findAll([options]) -> Promise.<Array.<Instance>>
查找范围==》id=1,2的对象
findAll({
'order': [['id', 'DESC']], //排序降序
where: {id: [1,2]} //筛选
})
返回原始结果
findAll({
raw: true
})
连表查询并统计count条数
post=await db.Post_list.findAndCountAll({
include: [{
model: db.Post_cate
}],
where: {'$post_cates.id$': req.body.cate_id},
raw: false
})

console.log(post,'全部文章');
```

##### `findById()` - 通过Id查询单条数据

```
findById(id, [options]) -> Promise.<Instance>
```

通过Id(主键)查询单个实例(单条数据)。

**参数**

| 名称 | 类型 | 说明 |
| ---------------------------- | -------------------------- | ---------------------------------- |
| id | Number \| String \| Buffer | 要查询实例的主键 |
| [options] | Object | |
| [options.transaction] | Transaction | 在事务中执行查询 |
| [options.searchPath=DEFAULT] | String | 指定schema的 search_path (仅 Postgres) |

##### `count()` - 统计查询结果数

```
count([options]) -> Promise.<Integer>
```

统计符合查询条件的结果总数。

如果提供了`include`,将计算匹配关联的数目

**参数**

| 名称 | 类型 | 说明 |
| ---------------------------- | ----------- | ---------------------------------------- |
| [options] | Object | |
| [options.where] | Object | 查询属性(条件) |
| [options.include] | Object | Include 选项 |
| [options.distinct] | boolean | 在主键上使用 COUNT(DISTINCT(col)), `Model.aggregate` 要使用其它列 |
| [options.attributes] | Object | 在 `group`中联合使用 |
| [options.group] | Object | 创建复杂统计时,会返回所需要的多行 |
| [options.transaction] | Transaction | 在事务中执行查询Transaction to run query under |
| [options.logging=false] | Function | 一个用于打印查询时所执行sql的函数 |
| [options.searchPath=DEFAULT] | String | 指定schema的 search_path (仅 Postgres) |
| [options.benchmark=false] | Boolean | 当打印SQL日志时同时输出查询执行时间(毫秒) |

##### `findAndCount()` - 分页查询

```
findAndCount([findOptions]) -> Promise.<Object>
```

查询由`offset/limit`指定的所有匹配行,并返回查询条件所匹配的总数量。

```
Model.findAndCountAll({
where: ...,
limit: 12,
offset: 12
}).then(function (result) {
...
})
```

在上面查询中,`result`是一个包含以两个属性的对象:

```
{
rows: [],
count:
}
```

`result.rows`是匹配的查询行,`result.count`是查询条件匹配的总数量。

如果提供了`include`,将计算匹配关联的数目

```
User.findAndCountAll({
include: [
{ model: Profile, required: true}
],
limit 3
});
```

#### 5.4、`update()` - 更新记录

```
// 修改每个`lastName`为`null`的记录修改为"Doe"
User.update({ lastName: "Doe" }, {
where: {
lastName: null
}
}).then(() => {
console.log("Done");
});

```

**参数**

| 名称 | 类型 | 说明 |
| ------------------------------- | ----------- | ----------------------------- |
| values | Object | |
| options | Object | |
| options.where | Object | 筛选条件 |
| [options.fields] | Array | 要更新字段,默认为全部 |
| [options.validate=true] | Boolean | 更新每条记录前进行验证 |
| [options.hooks=true] | Boolean | 在执行更新前/后创建钩子 |
| [options.individualHooks=false] | Boolean | 在执行更新前/后为每个实例创建钩子 |
| [options.sideEffects=true] | Boolean | 是否更新任何虚拟设置 |
| [options.returning=false] | Boolean | 返回受影响的行 (仅适用于 postgres) |
| [options.limit] | Number | 要更新的行数 (仅适用于 mysql 和 mariadb) |
| [options.transaction] | Transaction | 在事务中执行查询 |
| [options.silent=false] | Boolean | 如果为`true`,updatedAt字段将不会更新 |

#### 5.5 `destroy()` - 删除记录

```
destroy(options) -> Promise.<Integer>
// 删除每个名为 "Jane" 的记录
User.destroy({
where: {
firstName: "Jane"
}
}).then(() => {
console.log("Done");
});
```

删除多个实例,或设置deletedAt的时间戳为当前时间(当启用`paranoid`时)

执行成功后返回被删除的行数

**参数**

| 名称 | 类型 | 说明 |
| ------------------------------- | ----------- | ---------------------------------------- |
| options | Object | |
| [options.where] | Object | 筛选条件 |
| [options.hooks=true] | Boolean | 在执行前/后创建钩子 |
| [options.individualHooks=false] | Boolean | 在执行前/后为每个实例创建钩子 |
| [options.limit] | Number | 要删除的行数 |
| [options.force=false] | Boolean | 删除而不是设置 deletedAt 为当前时间戳 (仅启用 `paranoid` 时适用) |
| [options.truncate=false] | Boolean | 设置为`true`时,会使用`TRUNCATE`代替`DELETE FROM`,这时会忽略`where`和`limit`选项 |
| [options.cascade=false] | Boolean | 仅适用于连接查询时的`TRUNCATE`操作,截断所有外键匹配的表 |
| [options.transaction] | Transaction | 在事务中执行查询 |

### 6 关联关系

<https://itbilu.com/nodejs/npm/sequelize-docs-v5.html#creating-persistent-instances>

1. `BelongsTo`
2. `HasOne`
3. `HasMany`
4. `BelongsToMany`

### 相关文档

[中文文档](https://blog.csdn.net/sd19871122/article/details/85221206)

我的个人网站(相关技术文首发地)www.pengwang.xyz

基于Nodejs的sequelize操纵数据库的更多相关文章

  1. 转-基于NodeJS的14款Web框架

    基于NodeJS的14款Web框架 2014-10-16 23:28 作者: NodeJSNet 来源: 本站 浏览: 1,399 次阅读 我要评论暂无评论 字号: 大 中 小 摘要: 在几年的时间里 ...

  2. [Intel Edison开发板] 04、Edison开发基于nodejs和redis的服务器搭建

    一.前言 intel-iot-examples-datastore 是Intel提供用于所有Edison开发板联网存储DEMO所需要的服务器工程.该工程是基于nodejs和redis写成的一个简单的工 ...

  3. 浏览器自动刷新——基于Nodejs的Gulp LiveReload与VisualStudio完美结合。

    本文版权桂博客园和作者吴双共同所有,转载和爬虫请注明原文地址 http://www.cnblogs.com/tdws/p/6016055.html 写在前面 大家好我是博客园的蜗牛,博客园的蜗牛就是我 ...

  4. 基于NodeJS的全栈式开发

    前言 为了解决传统Web开发模式带来的各种问题,我们进行了许多尝试,但由于前/后端的物理鸿沟,尝试的方案都大同小异.痛定思痛,今天我们重新思考了“前后端”的定义,引入前端同学都熟悉的 NodeJS,试 ...

  5. 基于Nodejs生态圈的TypeScript+React开发入门教程

    基于Nodejs生态圈的TypeScript+React开发入门教程   概述 本教程旨在为基于Nodejs npm生态圈的前端程序开发提供入门讲解. Nodejs是什么 Nodejs是一个高性能Ja ...

  6. (转)也谈基于NodeJS的全栈式开发(基于NodeJS的前后端分离)

    原文链接:http://ued.taobao.org/blog/2014/04/full-stack-development-with-nodejs/ 随着不同终端(pad/mobile/pc)的兴起 ...

  7. MariaDB之基于Percona Xtrabackup备份大数据库[完整备份与增量备份]

    MariaDB之基于Percona Xtrabackup备份大数据库[完整备份与增量备份] 1.Xtrabackup的安装 percona-xtrabackup-2.2.3-4982.el6.x86_ ...

  8. node-odata: 基于 NodeJS 的 REST 框架

    该开源项目目前已被 OData 官网 (odata.org)收录 关于 node-odata node-odata 可以让你轻松创建 REST API, 并能使用 OData 协议的格式进行数据的查询 ...

  9. 基于JQuery+JSP的无数据库无刷新多人在线聊天室

    JQuery是一款非常强大的javascript插件,本文就针对Ajax前台和JSP后台来实现一个无刷新的多人在线聊天室,该实现的数据全部存储在服务端内存里,没有用到数据库,本文会提供所有源程序,需要 ...

随机推荐

  1. MySQL的utf8问题

    作者:brightwang 原文:https://www.jianshu.com/p/ab9aa8d4df7d 有时候用MySQL存储一些特殊字符时,有出现乱码问题. 我用的是UTF-8编码的客户端, ...

  2. 【leetcode每日两题】-Day1-简单题

    1. 两数之和 给定一个整数数组 nums 和一个目标值 target,请你在该数组中找出和为目标值的那 两个 整数,并返回他们的数组下标. 你可以假设每种输入只会对应一个答案.但是,数组中同一个元素 ...

  3. 数据分析学习 third week (7.29~8.4)

    概率分布简介 简单地介绍下常用概率分布的理论知识. 基础概念 1.概率 概率直观上是指一个事件发生可能性大小的数量指标 概率的统计定义:在不变的条件下,重复进行$n$次试验,事件$A$发生的频率稳定在 ...

  4. ipa包如何打包?ios打包ipa的四种方法分享

      今天带来的内容是ios打包ipa的四种方法.总结一下,目前.app包转为.ipa包的方法有以下几种,下面一起来看看吧!    1.Apple推荐的方式,即实用xcode的archive功能 Xco ...

  5. 基于 JavaEmail 简单的发送邮件点到点,一对多(图片和附件)之多收件人,多少送人

    if(!StringUtil.isEmpty(message_type_to)){ if (message_type_to.contains(",")) { String[] sp ...

  6. 01-java开发环境配置

    1 JDK.JRE.JVM的关系 JDK: java开发工具包 JRE: java运行时环境 JVM: java虚拟机 2 JDK下载 方式一:官网 方式二:该链接提供jdk1.6 ,jdk1.7 , ...

  7. 仅需1秒!搞定100万行数据:超强Python数据分析利器

    前言 使用Python进行大数据分析变得越来越流行.这一切都要从NumPy开始,它也是今天我们在推文介绍工具背后支持的模块之一. 2 Vaex Vaex是 一种更快.更安全.总体上更方便的方法,可以使 ...

  8. CSS可见格式化模型

    1.盒模型 1.1 盒子大小 盒模型描述了元素如何显示,以及如何相互作用.相互影响. 页面中的所有元素都被看作一个矩形盒子,这个盒子包含元素的内容.内边距.边框和外边距. 给元素应用的背景会作用于元素 ...

  9. 2020-06-02:千万级数据量的list找一个数据。

    福哥答案2020-06-02: 对于千万级长度的数组单值查找:序号小的,单线程占明显优势:序号大的,多线程占明显优势.单线程时间不稳定,多线程时间稳定. go语言测试代码如下: package mai ...

  10. 2020-06-01:百万级int数据量的一个array求和。

    福哥答案2020-06-01: fork/join. 对于百万级长度的数组求和,单线程和多线程下区别不大.对于千万级长度的数组求和,多线程明显变快,大概是单线程的2-3倍. go语言测试代码如下: p ...