模型基础
本教程介绍模型是什么, 以及怎么使用
概念
模型是 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'
});