重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。
本文更新不及时, 建议到原文地址查看:【node】sequelize数据库ORM框架使用教程。
注意:本文仅仅对sequelize v5 版本进行介绍,若你使用的不是v5版本,可能本文帮助不大。
sequelize
是一个基于Promise的关系数据库ORM框架,使用它可以轻松帮你完成对Postgres
, MySQL
, MariaDB
, SQLite
和 Microsoft SQL Server
这些数据库的增删改查。支持事务、关系查询和懒加载等等功能。你必须使用Node v6版本以上,这样才可以充分使用ES6功能。
https://github.com/demopark/sequelize-docs-Zh-CN
sequelize的安装除了它本身,还需要安装你使用的对应的数据库的驱动,因此相对其他node模块,它可能稍显复杂。
使用命令:
npm install sequelize --save
即可将其安装到你的项目中,并自动帮你把依赖写入package.json
文件。
这需要根据自己使用的数据库来安装对应的驱动程序,下面列出了大部分的驱动程序安装命令:
# 根据你使用的数据库选择一个
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进行编译,做好相应处理即可。
要使用它我们必须先创建一个相应实列:
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框架,本文仅介绍了一些基础方法,有更多详细的用法可以到官方网站查看相应文档:
Sequelize官网
如果阅读英语比较吃力,可以到这里查阅翻译中文版的文档:
Sequelize文档·中文版
Sequelize文档·中文版·Github地址