Nodejs ORM框架Sequelize(入門)

簡(jiǎn)介

Sequelize 是一個(gè)基于 promise 的 Node.js ORM, 目前支持 Postgres, MySQL, SQLite 和 Microsoft SQL Server. 它具有強(qiáng)大的事務(wù)支持, 關(guān)聯(lián)關(guān)系, 預(yù)讀和延遲加載,讀取復(fù)制等功能.
Sequelize 遵從 SEMVER. 支持 Node v6 及更高版本以便使用 ES6 功能.
中文文檔

版本

v6 中文文檔(測(cè)試版)
v5 中文文檔
v4 中文文檔 (停止更新)

Getting started - 入門

在本教程中,將通過(guò)簡(jiǎn)單地設(shè)置 Sequelize 來(lái)學(xué)習(xí)基礎(chǔ)知識(shí).

安裝

Sequelize 可通過(guò) npm ( 或 yarn ) 獲得.

// 通過(guò) npm 安裝
npm install --save sequelize

你還需要手動(dòng)安裝對(duì)應(yīng)的數(shù)據(jù)庫(kù)驅(qū)動(dòng)程序:

# 選擇對(duì)應(yīng)的安裝:
$ npm install --save pg pg-hstore # Postgres
$ npm install --save mysql2
$ npm install --save mariadb
$ npm install --save sqlite3
$ npm install --save tedious # Microsoft SQL Server

建立連接

要連接到數(shù)據(jù)庫(kù),你必須創(chuàng)建 Sequelize 實(shí)例. 這可以通過(guò)將連接參數(shù)分別傳遞給 Sequelize 構(gòu)造函數(shù)或傳遞單個(gè)連接 URI 來(lái)完成:

const Sequelize = require('sequelize');

//方法1:單獨(dú)傳遞參數(shù)
const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: /* 'mysql' | 'mariadb' | 'postgres' | 'mssql' 之一 */
});

// 方法2: 傳遞連接 URI
const sequelize = new Sequelize('postgres://user:pass@example.com:5432/dbname');

Sequelize 構(gòu)造函數(shù)采用了 Sequelize構(gòu)造函數(shù)的API參考 中記錄的大量參數(shù).

注意: 設(shè)置 SQLite

如果你正在使用 SQLite, 你應(yīng)該使用以下代碼:

const sequelize = new Sequelize({
  dialect: 'sqlite',
  storage: 'path/to/database.sqlite'
});

注意: 連接池 (生產(chǎn)環(huán)境)

如果從單個(gè)進(jìn)程連接到數(shù)據(jù)庫(kù),則應(yīng)僅創(chuàng)建一個(gè) Sequelize 實(shí)例. Sequelize 將在初始化時(shí)設(shè)置連接池. 可以通過(guò)構(gòu)造函數(shù)的 options 參數(shù)(使用options.pool)配置此連接池,如以下示例所示:

const sequelize = new Sequelize(/* ... */, {
  // ...
  pool: {
    max: 5,
    min: 0,
    acquire: 30000,
    idle: 10000
  }
});

Sequelize構(gòu)造函數(shù)API參考中了解更多信息. 如果從多個(gè)進(jìn)程連接到數(shù)據(jù)庫(kù),則必須為每個(gè)進(jìn)程創(chuàng)建一個(gè)實(shí)例,但每個(gè)實(shí)例應(yīng)具有最大連接池大小,以便遵守總的最大大小.例如,如果你希望最大連接池大小為 90 并且你有三個(gè)進(jìn)程,則每個(gè)進(jìn)程的 Sequelize 實(shí)例的最大連接池大小應(yīng)為 30.

測(cè)試連接

你可以使用 .authenticate() 函數(shù)來(lái)測(cè)試連接.

sequelize
  .authenticate()
  .then(() => {
    console.log('Connection has been established successfully.');
  })
  .catch(err => {
    console.error('Unable to connect to the database:', err);
  });

關(guān)閉連接

Sequelize 將默認(rèn)保持連接持續(xù),并對(duì)所有查詢使用相同的連接. 如果需要關(guān)閉連接,請(qǐng)調(diào)用sequelize.close()(這是異步的并返回Promise).

表建模

模型是一個(gè)擴(kuò)展 Sequelize.Model 的類. 模型可以用兩種等效方式定義. 第一個(gè)是Sequelize.Model.init(屬性,參數(shù)):

const Model = Sequelize.Model;
class User extends Model {}
User.init({
  // 屬性
  firstName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  lastName: {
    type: Sequelize.STRING
    // allowNull 默認(rèn)為 true
  }
}, {
  sequelize,
  modelName: 'user'
  // 參數(shù)
});

另一個(gè)是使用 sequelize.define:

const User = sequelize.define('user', {
  // 屬性
  firstName: {
    type: Sequelize.STRING,
    allowNull: false
  },
  lastName: {
    type: Sequelize.STRING
    // allowNull 默認(rèn)為 true
  }
}, {
  // 參數(shù)
});

在內(nèi)部, sequelize.define 調(diào)用 Model.init.

上面的代碼告訴 Sequelize 在數(shù)據(jù)庫(kù)中期望一個(gè)名為 users 的表,其中包含 firstNamelastName 字段. 默認(rèn)情況下,表名自動(dòng)復(fù)數(shù)(在當(dāng)下使用inflection 庫(kù)來(lái)執(zhí)行此操作).通過(guò)使用 freezeTableName:true 參數(shù)可以為特定模型停止此行為,或者通過(guò)使用Sequelize構(gòu)造函數(shù)中的 define 參數(shù)為所有模型停止此行為.

Sequelize 還默認(rèn)為每個(gè)模型定義了字段id(主鍵),createdAtupdatedAt. 當(dāng)然也可以更改此行為(請(qǐng)查看API參考以了解有關(guān)可用參數(shù)的更多信息).

更改默認(rèn)模型參數(shù)

Sequelize 構(gòu)造函數(shù)采用 define 參數(shù),它將更改所有已定義模型的默認(rèn)參數(shù).

const sequelize = new Sequelize(connectionURI, {
  define: {
    // `timestamps` 字段指定是否將創(chuàng)建 `createdAt` 和 `updatedAt` 字段.
    // 該值默認(rèn)為 true, 但是當(dāng)前設(shè)定為 false
    timestamps: false
  }
});

// 這里 `timestamps` 為 false,因此不會(huì)創(chuàng)建 `createdAt` 和 `updatedAt` 字段.
class Foo extends Model {}
Foo.init({ /* ... */ }, { sequelize });

// 這里 `timestamps` 直接設(shè)置為 true,因此將創(chuàng)建 `createdAt` 和 `updatedAt` 字段.
class Bar extends Model {}
Bar.init({ /* ... */ }, { sequelize, timestamps: true });

你可以在Model.init API 參考sequelize.define API 參考 中閱讀有關(guān)創(chuàng)建模型的更多信息.

將模型與數(shù)據(jù)庫(kù)同步

如果你希望 Sequelize 根據(jù)你的模型定義自動(dòng)創(chuàng)建表(或根據(jù)需要進(jìn)行修改),你可以使用sync方法,如下所示:

// 注意:如果表已經(jīng)存在,使用`force:true`將刪除該表
User.sync({ force: true }).then(() => {
  // 現(xiàn)在數(shù)據(jù)庫(kù)中的 `users` 表對(duì)應(yīng)于模型定義
  return User.create({
    firstName: 'John',
    lastName: 'Hancock'
  });
});

一次同步所有模型

你可以調(diào)用sequelize.sync()來(lái)自動(dòng)同步所有模型,而不是為每個(gè)模型調(diào)用sync().

生產(chǎn)環(huán)境注意事項(xiàng)

在生產(chǎn)環(huán)境中,你可能需要考慮使用遷移而不是在代碼中調(diào)用sync().閱讀 Migrations(遷移) 了解更多信息.

查詢

一些簡(jiǎn)單的查詢?nèi)缦滤?

// 查找所有用戶
User.findAll().then(users => {
  console.log("All users:", JSON.stringify(users, null, 4));
});

// 創(chuàng)建新用戶
User.create({ firstName: "Jane", lastName: "Doe" }).then(jane => {
  console.log("Jane's auto-generated ID:", jane.id);
});

// 刪除所有名為“Jane”的人
User.destroy({
  where: {
    firstName: "Jane"
  }
}).then(() => {
  console.log("Done");
});

// 將所有沒(méi)有姓氏的人改為“Doe”
User.update({ lastName: "Doe" }, {
  where: {
    lastName: null
  }
}).then(() => {
  console.log("Done");
});

Sequelize 有很多查詢參數(shù). 你將在下一個(gè)教程中了解有關(guān)這些內(nèi)容的更多信息. 也可以進(jìn)行原始SQL查詢,如果你真的需要它們.

Promises 和 async/await

如上所示,通常普遍使用 .then 調(diào)用,Sequelize 普遍使用 Promise. 這意味著,如果你的 Node 版本支持它,你可以對(duì)使用 Sequelize 進(jìn)行的所有異步調(diào)用使用 ES2017 async/await 語(yǔ)法.

此外,所有 Sequelize promises 實(shí)際上都是 Bluebird promises,所以你也可以使用豐富的 Bluebird API(例如,使用finally,tap,tapCatch,map,mapSeries等). 如果要設(shè)置任何 Bluebird 特定參數(shù),可以使用 Sequelize 內(nèi)部使用的Sequelize.Promise 訪問(wèn) Bluebird 構(gòu)造函數(shù).

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容