簡(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 的表,其中包含 firstName 和 lastName 字段. 默認(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(主鍵),createdAt和updatedAt. 當(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ù).