基於Nodejs的sequelize操縱數據庫


## 使用基於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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM