Sequelize 是一個基於 Promise 的 Node.js ORM,目前支持 Postgres、MySQL、SQLite 和 Microsoft SQL Server。它具有強大的事務支持,關聯關系、讀取和復制等功能。
所謂ORM是指對象關系映射,通過使用描述對象和數據庫之間映射的元數據,將面向對象語言程序中的對象自動持久化到關系數據庫中。本質上就是將數據從一種形式轉換到另外一種形式
以下以使用mysql數據庫作為案例
為了演示,首先新建文件夾初始化項目
$ mkdir sequelizeTest // 新建文件夾
$ cd sequelizeTest // 進入文件夾
$ npm init --yes // 初始化項目
1. 安裝
// Using NPM
$ npm install --save sequelize
// 使用哪種數據庫選擇不同的安裝
$ npm install --save mysql2
$ npm install --save pg pg-hstore # Postgres
$ npm install --save mariadb
$ npm install --save sqlite3
$ npm install --save tedious # Microsoft SQL Server
我這里安裝mysql2
2.數據庫連接測試
在項目文件夾下新建一個index.js
(async function() {
const Sequelize = require('sequelize');
// 第一個參數是數據庫名,第二個參數是數據庫用戶名,第三個參數密碼
// 第四個參數配置參數 包括地址,數據庫類型等
const sequelize = new Sequelize('list', 'root', '123456', {
host: 'localhost',
dialect: 'mysql'
});
// 測試是否連接函數
sequelize.authenticate()
.then(() => {
console.log('連接成功');
console.log("hello");
})
.catch(err => {
console.log(err);
})
})()
使用nodemon 作為熱更新啟動,這樣就不用每次重啟了
$ npm install nodemon -g
啟動項目
$ nodemon index
顯示如下,說明已成功
3.定義模型
用來表述(描述)數據庫表字段信息的對象,每一個模型對象表示數據庫中的一個表,后續對數據庫的操作都是通過對應的模型對象來完成的
modelName:模型名稱,自定義
attributes:模型中包含都數據,每一個數據映射對應表中都每一個字段
options:模型(表)的設置
attributes:字段值描述:
- type:字段類型,String|DataTypes
- allowNull:是否允許為空,默認為true
- defaultValue:默認值,默認為null
- unique:值唯一,默認為false
- primaryKey:是否為主鍵,默認為false
options:模型(表)的設置
- timestamps:是否給每條記錄添加 createdAt 和 updatedAt 字段,並在添加新數據和更新數據的時候自動設置這兩個字段的值,默認為true
- paranoid:設置 deletedAt 字段,當刪除一條記錄的時候,並不是真的銷毀記錄,而是通過該字段來標示,即保留數據,進行假刪除,默認為false
- freezeTableName:禁用修改表名; 默認情況下,sequelize將自動將所有傳遞的模型名稱(define的第一個參數)轉換為復數。 默認為false
- tableName:手動設置表的實際名稱
- 定義表索引 indexes:Array<Object>
每個索引對象可以設置的值
name:索引名稱,默認模型名稱+字段
fields: Array<string>,索引字段
unique:唯一索引,默認false
創建模型實例對象
一個模型類對應一個表,一個模型實例對象就是一條對應的表記錄,通過操作這個對象來關聯操作對應的表中的數據,操作模型類就是操作表,操作模型類對象就是操作該表中的某條記錄 模型類 - 表 模型實例 - 記錄
舉例:
新建數據庫list,新建一個users表 數據結構如下:
定義模型
(async function() {
const Sequelize = require('sequelize');
const sequelize = new Sequelize('list', 'root', '123456', {
host: 'localhost',
dialect: 'mysql'
});
const UsersModel = await sequelize.define('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
username: {
type: Sequelize.STRING(20),
allowNull: false
},
password: {
type: Sequelize.CHAR(32),
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}, {
tableName: 'users'
});
// UsersModel
// let user = UsersModel.build({
// username: "swnd",
// password: "q11111"
// });
// user = await user.save();
// console.log(user.get({'id': 3}));
})()
對於數據類型請參考 Sequelize - DataTypes。
4. 單表的增刪改
增
方式一:調用 build 方法后對象只存在於內存中,需要進一步調用 save 方法才會保存到數據庫中。
let user = UsersModel.build({
username: "swnd",
password: "q11111"
});
user = await user.save();
console.log(user.get({'id': 3}));
以上代碼運行后,終端將會輸出以下信息:
方式二:調用 create 方法后,會直接保存到數據庫中。
const user = UsersModel.create({
username: 'zhangsan',
password: '123456'
})
console.log(user.get({'id': 6}));
改
方案一
const hasUser = await UsersModel.findOne({
where: {
id: 6,
username: 'zhangsan'
}
});
hasUser.username = 'wanggangdan'
hasUser.save();
方案二
const hasUser = await UsersModel.findOne({
where: {
id: 6
}
});
const updatedUser = await hasUser.update({
username: "green"
});
hasUser.save();
限制更新某字段
// 方案一
const hasUser = await UsersModel.findOne({
where: {
id: 6
}
});
const updatedUser = await hasUser.update({
username: "green2",
password: '8888888888'
},{
fields: ['username'] // 只允許更新這個
});
// 方案二
const hasUser = await UsersModel.findOne({
where: {
id: 6
}
});
hasUser.username = 'wanggangdan'
hasUser.passwprd = '8989878888'
hasUser.save({ fields: ['username'] }); // 只允許更新這個
刪
const hasUser = await UsersModel.findOne({
where: {
id: 3
}
});
await hasUser.destroy();
如果我們啟用了 paranoid
(偏執)模式,destroy
的時候不會執行 DELETE
語句,而是執行一個 UPDATE
語句將 deletedAt
字段設置為當前時間(一開始此字段值為NULL
)。不過需要注意的是,僅當 timestamps=true
為 true 時,paranoid 模式才能生效。
未完待續
本篇測試代碼
(async function() {
const Sequelize = require('sequelize');
const sequelize = new Sequelize('list', 'root', '123456', {
host: 'localhost',
dialect: 'mysql'
});
const UsersModel = await sequelize.define('Users', {
id: {
allowNull: false,
autoIncrement: true,
primaryKey: true,
type: Sequelize.INTEGER
},
username: {
type: Sequelize.STRING(20),
allowNull: false
},
password: {
type: Sequelize.CHAR(32),
allowNull: false
},
createdAt: {
allowNull: false,
type: Sequelize.DATE
},
updatedAt: {
allowNull: false,
type: Sequelize.DATE
}
}, {
tableName: 'users'
});
// 增
// 方式一
// let user = UsersModel.build({
// username: "swnd",
// password: "q11111"
// });
// user = await user.save();
// console.log(user.get({'id': 3}));
// 方式二
// const user = UsersModel.build({
// username: 'zhangsan2',
// password: '123456'
// })
// console.log(user.get({'id': 6}));
// 改
const hasUser = await UsersModel.findOne({
where: {
id: 3
}
});
// hasUser.username = 'wanggangdan'
// hasUser.passwprd = '8989878888'
// hasUser.save({ fields: ['username'] }); // 只允許更新這個
// const updatedUser = await hasUser.update({
// username: "green2",
// password: '8888888888'
// },{
// fields: ['username'] // 只允許更新這個
// });
await hasUser.destroy();
})()