重要聲明:本文章僅僅代表了作者個人對此觀點的理解和表述。讀者請查閱時持自己的意見進行討論。
本文更新不及時, 建議到原文地址查看:【node】sequelize數據庫ORM框架使用教程。
注意:本文僅僅對sequelize v5 版本進行介紹,若你使用的不是v5版本,可能本文幫助不大。
一、sequelize 簡介
sequelize
是一個基於Promise的關係數據庫ORM框架,使用它可以輕鬆幫你完成對Postgres
, MySQL
, MariaDB
, SQLite
和 Microsoft SQL Server
這些數據庫的增刪改查。支持事務、關係查詢和懶加載等等功能。你必須使用Node v6版本以上,這樣纔可以充分使用ES6功能。
https://github.com/demopark/sequelize-docs-Zh-CN
二、安裝
sequelize的安裝除了它本身,還需要安裝你使用的對應的數據庫的驅動,因此相對其他node模塊,它可能稍顯複雜。
1、安裝sequelize
使用命令:
npm install sequelize --save
即可將其安裝到你的項目中,並自動幫你把依賴寫入package.json
文件。
2、安裝數據庫驅動程序
這需要根據自己使用的數據庫來安裝對應的驅動程序,下面列出了大部分的驅動程序安裝命令:
# 根據你使用的數據庫選擇一個
npm install --save pg pg-hstore # Postgres 數據庫
npm install --save mysql2 # mysql 數據庫
npm install --save mariadb # mariadb 數據庫
npm install --save sqlite3 # sqlite 數據庫
npm install --save tedious # SQL Server 數據庫
有些驅動程序安裝過程中可能會涉及到使用python進行編譯,做好相應處理即可。
三、創建sequelize實列
要使用它我們必須先創建一個相應實列:
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */
});
而對於SQlite數據庫,則應使用下面的方式來創建實列:
const sequelize = new Sequelize({
dialect: 'sqlite',
storage: 'path/to/database.sqlite' // sqlite 文件路徑
});
四、數據庫表與代碼實體
數據庫表與代碼實體的映射無疑是所有ORM框架的靈魂所在,sequelize
也同樣。其提供的Model
實體基類提供了大量與表操作相關的方法,學習它可以爲我們的業務帶來極大的便利。
要正常的使用Model
基類提供的各個服務,需要先使用其提供的靜態方法init(attr, options)
來完成初始化,這個過程不妨就放在我們的服務啓動的時候。下面示例了一個典型的初始化方式:
// User.js 用戶實體定義方案
const Sequelize = require('sequelize');
const Model = Sequelize.Model;
class User extends Model {};
module.exports = {
User,
init (sequelize) {
User.init({
id: {
primaryKey: true,
allowNull: false,
type: Sequelize.STRING
},
name: {
type:Sequelize.STRING,
allowNull: false
},
password: {
type: Sequelize.STRING,
allowNull: false
}
}, {
sequelize, modelName: 'user'/*表名*/
});
}
}
有了這樣的User(用戶)模塊定義,我們就可以在創建sequelize
的時候進行對其的初始化了:
const Sequelize = require('sequelize');
const UserModel = require('./User.js');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */
});
UserModel.init(sequelize); // 初始化
然後就可以愉快的使用了:
// UserService.js
const User = require("./User.js").User;
const userService = {
// 通過用戶id獲取指定用戶。
getUserById (userId) {
return User.findOne({
where: {id: userId}
});
}
};
module.exports = userService;
五、多表關聯查詢
Sequelize
在多表關聯查詢這一塊也有非常優雅的解決方案,單表查詢只需要提供一個where
查需語句,而多表查詢僅僅在此基礎上多出一個include
參數,用於告知在查詢時聯合哪一張表進行查詢。但要完成這個查詢是有條件的,如果說單張表查詢是因爲我們進行了init
初始化後才能進行的,那麼多張表查詢我們也必須要先完成哪些表有關聯關係
的這樣一個初始化過程。
不如就以比較常見的一對多關係來做示例,我們有一張User
表(見上第四節方定義),再來一張Message
表,這張表是這樣的:
// Message 表定義
// ┌────┬────────┬─────────┬────────────────────┐
// │ id │ userId │ content │ time │
// │────┼────────│─────────│────────────────────┤
// │ 01 │ 200023 │ Hello! │ 2020-3-17 00:00:00 │
// └────┴────────┴─────────┴────────────────────┘
//
// 下面是代碼定義
const Sequelize = require('sequelize');
const Model = Sequelize.Model;
class Message extends Model {};
module.exports = {
Message,
init (sequelize) {
Message.init({
id: {
primaryKey: true,
allowNull: false,
type: Sequelize.STRING
},
userId: {
type:Sequelize.STRING,
allowNull: false
},
content: {
type: Sequelize.STRING,
allowNull: false
},
time: {
type:Sequelize.DATE,
allowNull: false
}
}, {
sequelize, modelName: 'message'/*表名*/
});
}
}
通過字段userId
與User
表建立起關係,實現了記錄消息是通過誰發送出來的。先有需求:根據消息id查詢消息詳細信息,包含:消息內容、發消息時間、消息發送者名字
。而我們的message表顯然並沒有發送者名字
這個字段,所以我們不得不聯合User
表來進行查詢,從而實現我們的需求了。
上面說到,要聯合查詢,先要告知Message
金和User
表存在的關聯關係,這裏可以整理得出,消息(message)是由用戶(user)發送的,也就是消息屬於用戶。通過belongsTo
方法,我們可以方便的告知它們的關聯關係:
// ModelIniter.js
const MessageIniter = require("./Message.js");
const UserIniter = require("./User.js");
module.exports = {
init: function () {
MessageIniter.Message.belongsTo(UserIniter.User, {
foreignKey: "userId", // Message 表的 userId 字段
targetKey: "id" // 對應到 User 表的 id 字段
});
}
}
現在我們在程序啓動的時候,只需要引入並運行一下init方法:
const Sequelize = require('sequelize');
const UserModel = require('./User.js');
const MessageModel = require('./Message.js');
const ModelIniter = require('./ModelIniter.js');
const sequelize = new Sequelize('database', 'username', 'password', {
host: 'localhost',
dialect: /* one of 'mysql' | 'mariadb' | 'postgres' | 'mssql' */
});
UserModel.init(sequelize); // 初始化 User 實體
MessageModel.init(sequelize); // 初始化 Message 實體
ModelIniter.init(); // 初始化關聯關係
現在,我們可以開始聯合查詢了:
// MessageServices.js
const Message = require("./Message.js").Message;
const messageServices = {
// 通過用戶id獲取指定用戶。
getMessageById (msgId) {
return Message.findOne({
// 關聯 User 表查詢,只查詢 User 表的 name 字段,
// 並將 name 字段查詢結果重命名爲 userName
include: [{model: User, attributes: [
["name","userName"]
]}],
where: { id: msgId }
});
}
};
module.exports = messageServices;
六、更多
Sequelize
是一個龐大且完善的ORM框架,本文僅介紹了一些基礎方法,有更多詳細的用法可以到官方網站查看相應文檔:
如果閱讀英語比較吃力,可以到這裏查閱翻譯中文版的文檔: