什么是 Sequelize
Sequelize 是一个基于 promise 的 Node.js ORM, 目前反对 Postgres, MySQL, MariaDB, SQLite 以及 Microsoft SQL Server. 它具备弱小的事务反对, 关联关系, 预读和提早加载, 读取复制等性能。
简略说就是 nodejs 的 ORM 库, 满足大部分 SQL 数据库。
装置
npm i sequelize
# 装置数据库驱动程序
npm i pg pg-hstore # PostgreSQL
npm i mysql2 # MySQL
npm i sqlite3 # SQLite
npm i tedious # Microsoft SQL Server
npm i ibm_db # DB2
连贯数据库
const {Sequelize} = require("sequelize")
// Option 1: Passing a connection URI
const sequelize = new Sequelize('mysql://root:123456@localhost:3306/test')
// Option 2: Passing parameters separately
const sequelize = new Sequelize({
dialect: 'mysql', // 指定连贯的数据库类型
host: 'localhost',
username: 'root',
password: '123456',
})
参数请参照 API
测试连贯
try {await sequelize.authenticate();
console.log("连贯胜利")
} catch(error) {console.error('连贯失败:', error);
}
敞开连贯
通常 sequelize 一旦启用连贯后就会始终放弃连贯,但很容易导致 SQL 负载,所以 sequelize 也提供了一个形式敞开连贯,sequelize.close()
数据库编程大抵过程:
- 建库和建表
- 配置数据库连贯信息
- 建设数据库连贯或数据库连接池
- 拿到数据库连贯而后开启事务
- 执行数据库操作相干代码(如: select xxx)
- 提交事务
- 敞开数据库连贯或将数据库连贯偿还到数据库连接池
日志
默认状况下,Sequelize 会打印它执行的每一个 SQL 查问,能够通过传入自定义函数给 option.log
这个属性来来扭转打印日志的行为。它的默认值是console.log
,默认只显示日志函数的第一个参数。
const sequelize = new Sequelize('sqlite::memory:', {
// Choose one of the logging options
logging: console.log, // Default, displays the first parameter of the log function call
logging: (...msg) => console.log(msg), // Displays all log function call parameters
logging: false, // Disables logging
logging: msg => logger.debug(msg), // Use custom logger (e.g. Winston or Bunyan), displays the first parameter
logging: logger.debug.bind(logger) // Alternative way to use custom logger, displays all messages
});
关联
Sequelize 反对规范关联关系: 一对一, 一对多 和 多对多.
为此,Sequelize 提供了 四种 关联类型, 并将它们组合起来以创立关联:
- HasOne 关联类型
- BelongsTo 关联类型
- HasMany 关联类型
- BelongsToMany 关联类型
一对一关系
// Sequelize 晓得必须将 fooId 列增加到 Bar 中.
Foo.hasOne(Bar);
Bar.belongsTo(Foo);
能够依照生成 sql 去了解:// B belongsTo A
// where B.foreignKey = A.primaryKey
// A hasOne B
// where A.primaryKey = B.foreignKey
二者必须同时配置,才能够相互调用查问。
- 自定义外键
// 办法 1
Foo.hasOne(Bar, {
foreignKey: 'myFooId',
type: DataTypes.UUID
});
Bar.belongsTo(Foo, {
foreignKey: 'myFooId',
type: DataTypes.UUID // 可选
});
强制性与可选性关联
用的比拟少,理解即可
Foo.hasOne(Bar, {
foreignKey: {allowNull: false}
});
一对多关系
一个 Team 有 Player , 而每个 Player 都属于一个 Team.
Team.hasMany(Player);
Player.belongsTo(Team);
其余的参考一对一关系
多对多关系
多对多关系通常通过联结表来实现。
const Movie = sequelize.define('Movie', { name: DataTypes.STRING});
const Actor = sequelize.define('Actor', { name: DataTypes.STRING});
Movie.belongsToMany(Actor, { through: 'ActorMovies'});
Actor.belongsToMany(Movie, { through: 'ActorMovies'});
除了字符串以外, 还反对间接传递模型, 在这种状况下, 给定的模型将用作联结模型(并且不会主动创立任何模型). 例如:
const Movie = sequelize.define('Movie', { name: DataTypes.STRING});
const Actor = sequelize.define('Actor', { name: DataTypes.STRING});
const ActorMovies = sequelize.define('ActorMovies', {
MovieId: {
type: DataTypes.INTEGER,
references: {
model: Movie, // 'Movies' 也能够应用
key: 'id'
}
},
ActorId: {
type: DataTypes.INTEGER,
references: {
model: Actor, // 'Actors' 也能够应用
key: 'id'
}
}
});
Movie.belongsToMany(Actor, { through: ActorMovies});
Actor.belongsToMany(Movie, { through: ActorMovies});
连接池
业务服务器与数据库提前建设好连贯,并将这些连贯始终放弃,当有业务到来时,间接应用这些连贯来解决业务,这样的技术叫连接池技术。应用连接池可能缩小资源对象的创立次数,提⾼程序的响应性能,特地是在⾼并发下这种提⾼更加显著。比方在 mysql 连接池中,能够尽量避免连贯三次握手四次挥手等非业务流程带来的损耗。池化技术,实质上说就是资源复用。
如果要从单个过程连贯到数据库, 则应仅创立一个 Sequelize 实例. Sequelize 将在初始化时建设连接池. 能够通过构造函数的 options 参数 (应用 options.pool) 来配置此连接池, 如以下示例所示:
const sequelize = new Sequelize(/* ... */, {
// ...
pool: {
max: 5,
min: 0,
acquire: 30000,
idle: 10000
}
});
如果要从多个过程连贯到数据库, 则必须为每个过程创立一个实例, 然而每个实例的最大连接池大小应达到最大总大小. 例如, 如果你心愿最大连接池大小为 90, 并且有三个过程, 则每个过程的 Sequelize 实例的最大连接池大小应为 30.
参考文章
- 解决 sequelize 嵌套过深问题
- 对于应用 Sequelize 进行数据库连贯 / 开释方面的解惑
- Sequelize 的读写拆散