模型基础
本教程介绍模型是什么, 以及怎么使用
概念
模型是 Sequelize 的核心. 模型是数据库中表的抽象. 在 Sequelize 中模型是派生自 Model 的类.
模型告诉 Sequelize 很多信息, 例如表名是什么, 列名是什么, 以及是什么数据类型等.
Sequelize 中模型也有名字 (name). 这个名字与数据库中表的名字不一定相同 (可以不同).
大部分情况下, 模型是单数名词, 例如 User, 而表示复数名词, 例如 Users. 但是这也是可以配置的.
模型定义
有两种方法:
- 调用
sequelize.define(modelName, attributes, options) - 继承
Model, 调用init(attribute, options)
模型定义后, 可以使用模型的名字在 sequelize.models 中访问.
利用一个案例进行说明.
- 需要创建一个 user 模型
- 该模型有
firstName和lastName属性 - 并且模型的名字为:
User - 数据表的名字为:
Users
下面给出两个语法的定义示例, 完成定义后, 可以使用 sequelize.models.User 来访问模型.
使用 sequelize.define
const { Sequeslize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('sqlite::memory');
const User = sequelize.define('User', {
// 此处定义模型的属性 (attribute)
firstName: {
type: DataType.STRING,
allowNull: false,
},
lastName: {
type: DataTypes.STRING,
// allowNull 默认为 true
}
}, {
// 其他选项配置在这里
});
// sequelize.define 返回 model
console.log(User === sequelize.models.User); // => true
派生自 Model
const { Sequeslize, DataTypes, Model } = require('sequelize')
const sequelize = new Sequelize('sqlite::memory')
class User extends Model {}
User.init({
// 此处定义模型属性 (attribute)
firstName: {
type: DataTypes.STRING,
allowNull: false
},
lastName: {
type: DataTypes.STRING,
// allowNull 默认为 true
}
}, {
// 其他选项写在这里
sequelize, // 我们需要传入连接实例
modelName: 'User', // 用于定义模型名
});
console.log(User === sequelize.models.User); // => true
实际上, Sequelize 内部 sequelize.define 调用的是 Model.init, 因此两个方法是等价的.
公共类字段警告 (Caveat with Public Class Fields)
添加与模型属性 (attribute) 同名的公共字段会被警告.
Sequelize 内部会对每一个模型属性进行 getter 与 setter 处理, 添加公共属性后会隐藏这些读写器, 从而使得访问模型数据被阻塞.
在 TypeScript 中, 不用添加公共类字段, 可以使用 declare 关键字来添加类型信息:
class User extends Model {
declare id: number;
}
User.init({
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true,
}
}, { sequelize });
const user = new User({ id: 1 })
表名的推断
上述的两个语法都没有定义表名, 但是表名为 Users.
默认情况下, 没有显式定义表名时, Sequelize 会默认将模型名转化为复数形式, 即 Users. 这个转化底层采用 inflection 来完成, 可以进行不规则名词的复数化问题.
当然, 这个操作也是可以配置的.
让表名与模型名一样
使用选项 freezeTableName: true, 那么会使用模型名作为表名, 不会进行任何改变.
sequelize.define('User', {
// 属性定义
}, {
freezeTableName: true
});
这个选项可以定义在全局的 Sequelize 实例上:
const sequelize = new Sequelize('sqlite::memory', {
define: {
freezeTableName; true
}
});
如此, 所有的表名与模型名都会一样.
直接提供表名
使用属性 tableName 直接为模型定义表名:
sequelize.define('User', {
// 属性 (attribute)
}, {
tableName: 'Employees'
});