jk's notes
  • 模型基础

模型基础

本教程介绍模型是什么, 以及怎么使用

概念

模型是 Sequelize 的核心. 模型是数据库中表的抽象. 在 Sequelize 中模型是派生自 Model 的类.

模型告诉 Sequelize 很多信息, 例如表名是什么, 列名是什么, 以及是什么数据类型等.

Sequelize 中模型也有名字 (name). 这个名字与数据库中表的名字不一定相同 (可以不同).

大部分情况下, 模型是单数名词, 例如 User, 而表示复数名词, 例如 Users. 但是这也是可以配置的.

模型定义

有两种方法:

  • 调用 sequelize.define(modelName, attributes, options)
  • 继承 Model, 调用 init(attribute, options)

模型定义后, 可以使用模型的名字在 sequelize.models 中访问.

利用一个案例进行说明.

  1. 需要创建一个 user 模型
  2. 该模型有 firstName 和 lastName 属性
  3. 并且模型的名字为: User
  4. 数据表的名字为: 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'
});

模型同步

Last Updated:
Contributors: jk