自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

學會Sequelize,讓你操作數(shù)據(jù)更絲滑!

開發(fā) 前端
Sequelize 支持多種類型的模型關(guān)聯(lián),包括一對一(One-to-One)、一對多(One-to-Many)和多對多(Many-to-Many)等。通過定義模型之間的關(guān)聯(lián)關(guān)系,我們可以方便地執(zhí)行跨表查詢、創(chuàng)建、更新以及刪除操作,而無需手動編寫復(fù)雜的 JOIN 查詢。

本文來介紹 Sequelize,一個基于 Node.js 的 ORM(對象關(guān)系映射)工具,并詳細介紹其用法。Sequelize 用于在應(yīng)用中使用 JavaScript 來操作關(guān)系型數(shù)據(jù)庫,例如 MySQL、PostgreSQL 等。本文內(nèi)容較多,可作為 Sequelize 的參考手冊來閱讀。

開始使用

核心概念

Sequelize 是一個基于 JavaScript 的 ORM(對象關(guān)系映射)庫,用于在 Node.js 環(huán)境中與數(shù)據(jù)庫進行交互。它提供了一種方便、靈活的方式來管理數(shù)據(jù)庫,并將數(shù)據(jù)庫表映射為對象,使開發(fā)人員可以使用面向?qū)ο蟮木幊田L格來操作數(shù)據(jù)庫。

ORM(對象關(guān)系映射)是一種編程技術(shù),用于通過將對象和數(shù)據(jù)庫表之間建立映射關(guān)系,以更直觀的方式進行數(shù)據(jù)庫操作。Sequelize 通過將數(shù)據(jù)庫記錄映射為模型對象,使得開發(fā)人員可以使用 JavaScript 對象的方法和屬性來進行數(shù)據(jù)庫的增刪改查操作,而不需要編寫復(fù)雜的 SQL 查詢語句。

Sequelize 支持多種數(shù)據(jù)庫,包括 MySQL、PostgreSQL、SQLite 和 MSSQL 等,可以適應(yīng)各種不同的項目需求。它提供了豐富的功能,包括模型定義、關(guān)聯(lián)關(guān)系、事務(wù)處理、查詢構(gòu)建器等,可以幫助開發(fā)人員高效地進行數(shù)據(jù)庫操作。

使用 Sequelize,開發(fā)人員可以輕松地進行數(shù)據(jù)庫遷移、執(zhí)行復(fù)雜的查詢和聚合操作,并實現(xiàn)數(shù)據(jù)校驗和驗證等功能。此外,它還提供了鉤子函數(shù)、事件觸發(fā)和數(shù)據(jù)庫連接池等功能,以優(yōu)化數(shù)據(jù)庫訪問性能。

基本使用

要使用 Sequelize 來連接 MySQL 數(shù)據(jù)庫,需要進行以下步驟:

  1. 安裝 Sequelize 和 MySQL 驅(qū)動程序:
  • 使用 npm 運行以下命令來安裝 Sequelize:npm install sequelize
  • 安裝 MySQL:npm install mysql2
  1. 創(chuàng)建 Sequelize 實例和數(shù)據(jù)庫連接:
const { Sequelize } = require('sequelize');

const sequelize = new Sequelize('database', 'username', 'password', {
  host: 'localhost',
  dialect: 'mysql',
});

這里需要將 'database'、'username' 和 'password' 分別替換為 MySQL 數(shù)據(jù)庫的名稱、用戶名和密碼。還可以根據(jù)需要設(shè)置其他連接選項,例如 host 和 port。

  1. 定義模型:
const User = sequelize.define('User', {
  username: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true,
    },
  },
  // 其他屬性和選項
});

這里定義了一個名為 User 的模型,包含 username 和 email 屬性。

  1. 進行數(shù)據(jù)庫操作:
async function createUser() {
  await sequelize.sync(); // 同步模型和數(shù)據(jù)庫

  const user = await User.create({ username: 'John', email: 'john@example.com' });
  console.log(user.toJSON());
}

createUser().catch(console.error);

這里首先調(diào)用 sequelize.sync() 方法來同步模型和數(shù)據(jù)庫,以確保模型在數(shù)據(jù)庫中存在。然后使用 User.create() 方法創(chuàng)建一個新用戶,并輸出其序列化后的 JSON 數(shù)據(jù)。

這只是 Sequelize 連接 MySQL 的基本用法,你還可以使用 Sequelize 提供的其他方法來執(zhí)行查詢、更新、刪除等操作,以及定義模型之間的關(guān)聯(lián)關(guān)系。下面會詳細介紹!

模型定義

在 Sequelize 中,模型(Model)是一種表示數(shù)據(jù)庫表結(jié)構(gòu)的抽象化概念。它定義了數(shù)據(jù)表的結(jié)構(gòu)和行為,包括表名、字段、關(guān)聯(lián)關(guān)系、數(shù)據(jù)校驗規(guī)則等。

Sequelize 模型允許通過編寫模型類來操作數(shù)據(jù)庫表,封裝了對數(shù)據(jù)庫的增刪改查等操作。每個模型類對應(yīng)一個數(shù)據(jù)庫表,并且模型類的實例代表數(shù)據(jù)庫表中的一條記錄。

創(chuàng)建模型

定義模型方法

可以使用sequelize.define() 方法來創(chuàng)建模型,它用于定義和創(chuàng)建模型,其基本語法如下:

sequelize.define(modelName, attributes, options)

參數(shù)說明:

  • modelName:模型的名稱。
  • attributes:模型的屬性定義,一個包含列名和數(shù)據(jù)類型的對象。
  • options:模型的其他選項,例如表名、時間戳等。
const { Sequelize, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password');

const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  username: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  email: {
    type: DataTypes.STRING,
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true,
    },
  },
  createdAt: {
    type: DataTypes.DATE,
    allowNull: false,
    defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
  },
  updatedAt: {
    type: DataTypes.DATE,
    allowNull: false,
    defaultValue: Sequelize.literal('CURRENT_TIMESTAMP'),
  },
}, {
  tableName: 'users',
  timestamps: true,
});

// 創(chuàng)建用戶實例
User.create({ username: 'John', email: 'john@example.com' })
  .then((user) => {
    console.log(user.toJSON());
  })
  .catch(console.error);

這里使用 sequelize.define() 方法定義了一個名為 User 的模型。模型具有 id、username、email、createdAt 和 updatedAt 等屬性。我們還指定了表名為 'users',以及啟用了時間戳屬性。

定義模型步驟

在 Sequelize 中,創(chuàng)建模型的步驟如下:

  1. 配置 Sequelize 實例連接數(shù)據(jù)庫,確定數(shù)據(jù)庫的相關(guān)信息。
  2. 使用 sequelize.define 方法定義模型,并指定模型的名稱、字段和其他選項。
  3. 通過調(diào)用模型的 sync 方法將模型同步到數(shù)據(jù)庫中。
const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  // 配置數(shù)據(jù)庫連接信息
});

// 定義模型
const User = sequelize.define('User', {
  name: Sequelize.STRING,
  email: Sequelize.STRING,
  age: Sequelize.INTEGER,
});

// 同步模型到數(shù)據(jù)庫
(async () => {
  try {
    await sequelize.sync();
    console.log('模型創(chuàng)建成功!');
  } catch (error) {
    console.error('模型創(chuàng)建失?。?, error);
  } finally {
    sequelize.close(); // 關(guān)閉數(shù)據(jù)庫連接
  }
})();

記得在最后關(guān)閉 Sequelize 連接,避免資源泄漏。

注意,模型創(chuàng)建后只需調(diào)用 sequelize.sync 方法進行同步一次即可,后續(xù)對模型的修改不會自動同步到數(shù)據(jù)庫。如果想要更新現(xiàn)有的模型定義,可以使用 Sequelize 提供的遷移工具或手動修改數(shù)據(jù)庫表結(jié)構(gòu)。

定義模型參數(shù)

上面的例子只定義了字段的類型,其實還有很多屬性可以定義,下面來看一個例子:

const Sequelize = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password', {
  // 配置數(shù)據(jù)庫連接信息
});

const User = sequelize.define('User', {
  name: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  email: {
    type: Sequelize.STRING,
    allowNull: false,
    unique: true,
    validate: {
      isEmail: true,
    },
  },
  age: {
    type: Sequelize.INTEGER,
    allowNull: false,
    defaultValue: 0,
    validate: {
      min: 0,
    },
  },
});

在字段定義對象中,每個屬性表示一個字段。屬性的名稱是字段的名稱,屬性的值是字段的配置。下面來分別看看這些字段值。

type:參數(shù)類型

type 屬性用于指定模型字段的數(shù)據(jù)類型。以下是一些常見的數(shù)據(jù)類型選項:

  • STRING:字符串類型。
  • CHAR:字符型,允許存儲固定長度的字符串。
  • TEXT:文本類型,適用于存儲大段文本數(shù)據(jù)。
  • INTEGER:整數(shù)類型。
  • BIGINT:大整數(shù)類型。
  • FLOAT:浮點數(shù)類型。
  • DOUBLE:雙精度浮點數(shù)類型。
  • DECIMAL:十進制數(shù)類型。
  • BOOLEAN:布爾類型。
  • DATE:日期類型,不包括時間。
  • TIME:時間類型,不包括日期。
  • DATEONLY:僅日期類型。
  • DATETIME:日期和時間類型。
  • BLOB:二進制大對象類型,適用于存儲二進制數(shù)據(jù)。
  • UUID:通用唯一識別碼類型。

此外,Sequelize 還支持將數(shù)據(jù)類型與修飾符結(jié)合使用,以提供更豐富的數(shù)據(jù)定義選項。例如:

  • STRING(100):指定字符串類型的最大長度為 100 個字符。
  • INTEGER.UNSIGNED:指定無符號整數(shù)類型。
  • DECIMAL(10, 2):指定十進制數(shù)類型,并設(shè)置總共10位數(shù),其中包含2位小數(shù)。
數(shù)字類型

在 Sequelize 中,數(shù)字類型包括以下幾種:

  • INTEGER:表示整數(shù)類型。可以使用 Sequelize.INTEGER 或 Sequelize.INTEGER(n) 來定義,其中 n 是整數(shù)的位數(shù)。
  • BIGINT:表示長整數(shù)類型??梢允褂?nbsp;Sequelize.BIGINT 或 Sequelize.BIGINT(n) 來定義,其中 n 是長整數(shù)的位數(shù)。
  • FLOAT:表示單精度浮點數(shù)類型??梢允褂?nbsp;Sequelize.FLOAT 或 Sequelize.FLOAT(n, m) 來定義,其中 n 是總位數(shù),m 是小數(shù)部分的位數(shù)。
  • DOUBLE:表示雙精度浮點數(shù)類型??梢允褂?nbsp;Sequelize.DOUBLE 或 Sequelize.DOUBLE(n, m) 來定義,其中 n 是總位數(shù),m 是小數(shù)部分的位數(shù)。
  • DECIMAL:表示任意精度的十進制數(shù)類型??梢允褂?nbsp;Sequelize.DECIMAL 或 Sequelize.DECIMAL(n, m) 來定義,其中 n 是總位數(shù),m 是小數(shù)部分的位數(shù)。
字符串類型

在 Sequelize 中,字符串類型有以下幾種選項可供選擇:

  • STRING:表示普通的字符串類型??梢允褂?nbsp;Sequelize.STRING 來定義,默認最大長度為 255 個字符。
  • CHAR:表示定長的字符串類型。你可以指定最大長度作為選項??梢允褂?nbsp;Sequelize.CHAR(length) 來定義,其中 length 是字符串的最大長度。
  • TEXT:表示長文本類型??梢源鎯Ω箝L度的文本數(shù)據(jù)??梢允褂?nbsp;Sequelize.TEXT 來定義。
  • UUID:表示 UUID 字符串類型,用于存儲全局唯一標識符??梢允褂?nbsp;Sequelize.UUID 來定義。
  • ENUM:表示枚舉類型,用于存儲預(yù)定義的選項列表中的一個值。需要提供一個選項數(shù)組作為參數(shù)。可以使用 Sequelize.ENUM(values) 來定義,其中 values 是枚舉選項的數(shù)組。
  • JSON:表示存儲 JSON 數(shù)據(jù)的字符串類型??梢允褂?nbsp;Sequelize.JSON 來定義。
  • JSONB:表示存儲 JSONB(二進制格式的 JSON)數(shù)據(jù)的字符串類型(僅支持 PostgreSQL)??梢允褂?nbsp;Sequelize.JSONB 來定義。
日期類型

在 Sequelize 中,日期類型包括以下幾種:

  • DATE:表示日期類型,不包含時間??梢允褂?nbsp;Sequelize.DATE 來定義。
  • TIME:表示時間類型,不包含日期??梢允褂?nbsp;Sequelize.TIME 來定義。
  • DATETIME:表示日期和時間類型??梢允褂?nbsp;Sequelize.DATE 或 Sequelize.DATETIME 來定義。
  • NOW:表示當前時間??梢允褂?nbsp;Sequelize.NOW 來獲取當前時間的值。
  • DATEONLY:表示只包含日期的類型,不包含時間??梢允褂?nbsp;Sequelize.DATEONLY 來定義。
  • SMALLDATETIME:表示包含日期和時間的類型,時間精度較低。可以使用 Sequelize.SMALLDATETIME 來定義。
  • TIMESTAMP:表示包含日期和時間的類型,時間精度高于 SMALLDATETIME??梢允褂?nbsp;Sequelize.TIMESTAMP 來定義。
UUID類型

在 Sequelize 中,UUID 類型用于表示一個全局唯一的標識符。Sequelize 支持以下幾種 UUID 類型:

  • UUID:表示標準 UUID 字符串,長度為 36 個字符??梢允褂?nbsp;Sequelize.UUID 來定義。
  • UUIDV1:表示基于時間戳和 MAC 地址生成的 UUID 字符串??梢允褂?nbsp;Sequelize.UUIDV1 來獲取該類型的默認值。
  • UUIDV4:表示隨機生成的 UUID 字符串??梢允褂?nbsp;Sequelize.UUIDV4 來獲取該類型的默認值。
allowNull:是否可以為空

allowNull 是 Sequelize 中用于定義模型字段是否允許為空的屬性選項。

當 allowNull 設(shè)置為 true 時,表示該字段允許為空。這意味著在創(chuàng)建記錄或更新記錄時,可以將該字段設(shè)置為空值(null)。如果設(shè)置為 false,表示該字段不能為空。

defaultValue:默認值

defaultValue 用于定義模型字段默認值的屬性選項。

當創(chuàng)建記錄時,如果沒有提供該字段的值,則會使用 defaultValue 屬性定義的默認值。

primaryKey:主鍵值

primaryKey 是用于指定模型字段作為主鍵的屬性選項。

主鍵是數(shù)據(jù)庫表中的一種特殊字段,它用于唯一標識表中的每一行記錄。主鍵字段的值在整個表中必須是唯一的,并且不能為空。通過將 primaryKey 設(shè)置為 true,可以指示 Sequelize 將該字段設(shè)置為模型的主鍵。

autoIncrement:自增字段

autoIncrement 是一個用于指定模型字段是否為自增字段的屬性選項。

自增字段是一種特殊類型的主鍵,它的值會在每次插入新記錄時自動遞增。通常用于為每個新記錄分配唯一的標識符。自增字段的常見類型為整數(shù)(例如,INTEGER)。通過將 autoIncrement 設(shè)置為 true,可以指示 Sequelize 將該字段設(shè)置為自增字段。

使用自增字段可以方便地生成唯一的標識符,而無需顯式指定每個新記錄的值。數(shù)據(jù)庫在插入新記錄時會自動遞增該字段的值。這對于需要快速添加新記錄并確保主鍵唯一性的情況非常有用。

注意,autoIncrement 屬性僅對整數(shù)類型的字段有效。

unique:是否唯一

unique 用于定義模型字段是否唯一的屬性選項。

當將 unique 設(shè)置為 true 時,表示該字段的值必須在整個表中是唯一的。也就是說,在同一列中,每個記錄都必須有一個唯一的值,不能重復(fù)。

validate:校驗規(guī)則

validate 是用于定義模型字段驗證規(guī)則的屬性選項。

通過 validate 屬性,可以定義一個包含驗證規(guī)則的對象,用于驗證模型字段的值是否符合指定的條件。validate 屬性可以包含多個驗證規(guī)則,每個規(guī)則可以是一個函數(shù)或一個對象。下面是一些常見的驗證規(guī)則屬性值:

  • notEmpty:確保字段的值不為空。
  • len:檢查字段的長度是否在指定范圍內(nèi)??梢栽O(shè)置一個數(shù)組,如 [min, max]。
  • isEmail:驗證字段的值是否為有效的電子郵件地址。
  • isUrl:驗證字段的值是否為有效的 URL。
  • isAlpha:驗證字段的值是否只包含字母字符。
  • isAlphanumeric:驗證字段的值是否只包含字母和數(shù)字字符。
  • isNumeric:驗證字段的值是否為數(shù)字。
  • isInt:驗證字段的值是否為整數(shù)。
  • isFloat:驗證字段的值是否為浮點數(shù)。
  • isDate:驗證字段的值是否為有效的日期。
  • isAfter:驗證字段的值是否在指定日期之后。
  • isBefore:驗證字段的值是否在指定日期之前。
  • isIn:驗證字段的值是否在指定的數(shù)組中。

這只是一些常見的驗證規(guī)則,Sequelize 還提供了更多的內(nèi)置驗證規(guī)則。此外,你還可以定義自定義的驗證函數(shù)來進行復(fù)雜的驗證邏輯。

const User = sequelize.define('User', {
  username: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: {
      notEmpty: true,
      len: [3, 20],
      isAlphanumeric: true,
    },
  },
  email: {
    type: Sequelize.STRING,
    allowNull: false,
    validate: {
      isEmail: true,
    },
  },
});
comment:注釋

comment 是用于為模型字段添加注釋的屬性選項。

注釋是對字段的描述性文本,可以提供關(guān)于字段用途、含義或其他相關(guān)信息的補充說明。注釋對于理解和維護數(shù)據(jù)庫結(jié)構(gòu)非常有幫助。

const User = sequelize.define('User', {
  username: {
    type: Sequelize.STRING,
    comment: '用戶的用戶名', // 字段注釋
  },
  email: {
    type: Sequelize.STRING,
    comment: '用戶的電子郵件地址', // 字段注釋
  },
});
field:字段重命名

field 是一個用于指定模型字段在數(shù)據(jù)庫中的實際名稱的屬性選項。

默認情況下,Sequelize 會將模型定義中的字段名稱直接映射到數(shù)據(jù)庫表中對應(yīng)的列名。但是,有時可能希望在數(shù)據(jù)庫中使用不同的列名,這時可以使用 field 屬性來指定實際的數(shù)據(jù)庫列名。

const User = sequelize.define('User', {
  firstName: {
    type: Sequelize.STRING,
    field: 'first_name', // 指定數(shù)據(jù)庫對應(yīng)的列名
  },
  lastName: {
    type: Sequelize.STRING,
    field: 'last_name', // 指定數(shù)據(jù)庫對應(yīng)的列名
  },
});

在上述示例中,firstName 字段的 field 屬性設(shè)置為 first_name,lastName 字段的 field 屬性設(shè)置為 last_name。這將導(dǎo)致在數(shù)據(jù)庫表中創(chuàng)建名為 first_name和last_name 的列。

使用 field 屬性可以非常靈活地控制模型字段與數(shù)據(jù)庫列的映射關(guān)系。這在需要與遺留數(shù)據(jù)庫或特定數(shù)據(jù)庫命名約定交互的情況下非常有用。

注意,如果不指定 field 屬性,Sequelize 將默認使用與模型字段名稱相同的列名。

get 和 set:字段值計算
get

get 字段表示一個自定義的 getter 方法。它是一個通過訪問模型實例屬性來獲取計算值的函數(shù)。

使用 get 字段,可以定義一個自定義的 getter 方法,該方法會在訪問特定屬性時被調(diào)用,以便根據(jù)需要對屬性進行計算、處理或轉(zhuǎn)換。

const User = sequelize.define('User', {
  firstName: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  lastName: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  fullName: {
    type: Sequelize.VIRTUAL, // 虛擬屬性
    get() {
      return `${this.firstName} ${this.lastName}`;
    },
  },
});

const user = User.build({
  firstName: 'Alice',
  lastName: 'Smith',
});

console.log(user.fullName); // 輸出:Alice Smith

使用 get 字段可以方便地在訪問模型屬性時進行額外的計算或處理。它使得模型實例的屬性具有更多的靈活性和復(fù)雜性。

set

set 字段表示一個自定義的 setter 方法。它允許你在設(shè)置屬性值時執(zhí)行一些自定義邏輯或轉(zhuǎn)換。

使用 set 字段,可以定義一個自定義的 setter 方法,該方法會在設(shè)置特定屬性的值時被調(diào)用,以便對該值進行處理、驗證或轉(zhuǎn)換。

const User = sequelize.define('User', {
  fullName: {
    type: Sequelize.STRING,
    set(value) {
      const names = value.split(' ');
      this.setDataValue('firstName', names[0]);
      this.setDataValue('lastName', names[1]);
    },
  },
});

const user = User.build();
user.fullName = 'Alice Smith';

console.log(user.firstName); // 輸出:Alice
console.log(user.lastName); // 輸出:Smith

當給 user.fullName 賦值時,Sequelize 將自動調(diào)用定義的 setter 方法,并進行相應(yīng)的屬性設(shè)置。

使用 set 字段可以方便地在設(shè)置模型屬性值時執(zhí)行自定義的邏輯或轉(zhuǎn)換操作。它使得模型屬性的賦值具有更多的靈活性和復(fù)雜性。

references:模型關(guān)聯(lián)

references 是一個模型定義中的選項,用于指定關(guān)聯(lián)關(guān)系中引用的目標模型和目標屬性。

當在 Sequelize 模型定義中使用 references 選項,它表示當前模型與另一個模型之間的關(guān)聯(lián)關(guān)系,并指定了相關(guān)聯(lián)的目標模型和目標屬性。

const User = sequelize.define('User', {
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  username: {
    type: Sequelize.STRING,
    allowNull: false,
  },
});

const Post = sequelize.define('Post', {
  id: {
    type: Sequelize.INTEGER,
    primaryKey: true,
    autoIncrement: true,
  },
  title: {
    type: Sequelize.STRING,
    allowNull: false,
  },
  userId: {
    type: Sequelize.INTEGER,
    references: {
      model: User, // 引用的目標模型
      key: 'id', // 引用的目標屬性
    },
  },
});

這里定義了兩個模型:User 和 Post。在 Post 模型的定義中,使用了 references 選項來創(chuàng)建一個與 User 模型的關(guān)聯(lián)關(guān)系。

references 選項包含兩個屬性:

  • model:指定關(guān)聯(lián)的目標模型,這里是 User。
  • key:指定關(guān)聯(lián)的目標屬性,這里是 id。

這意味著 Post 模型中的 userId 屬性將引用 User 模型中的 id 屬性作為關(guān)聯(lián)。這意味著 userId 和 User 模型的 id 屬性具有相同的值。

通過使用 references 選項,Sequelize 可以根據(jù)關(guān)聯(lián)關(guān)系設(shè)置合適的數(shù)據(jù)庫約束,并幫助你在查詢中輕松處理模型之間的關(guān)聯(lián)。

onDelete:刪除關(guān)聯(lián)

onDelete 是一個定義關(guān)聯(lián)關(guān)系時可以設(shè)置的選項之一。它用于指定當關(guān)聯(lián)模型的記錄被刪除時要執(zhí)行的操作。

使用 onDelete 選項,可以定義在刪除關(guān)聯(lián)模型的記錄時應(yīng)該執(zhí)行的操作,例如級聯(lián)刪除、設(shè)置為 null 或什么都不做等。

以下是一些常用的 onDelete 選項值及其含義:

  • CASCADE:級聯(lián)刪除。當關(guān)聯(lián)模型的記錄被刪除時,與之關(guān)聯(lián)的記錄也將被刪除。
  • SET NULL:設(shè)置為 null。當關(guān)聯(lián)模型的記錄被刪除時,與之關(guān)聯(lián)的記錄的外鍵值將被設(shè)置為 null。
  • SET DEFAULT:設(shè)置為默認值。當關(guān)聯(lián)模型的記錄被刪除時,與之關(guān)聯(lián)的記錄的外鍵值將被設(shè)置為默認值。
  • RESTRICT:限制。當關(guān)聯(lián)模型的記錄被刪除時,如果還有與之關(guān)聯(lián)的記錄存在,則會阻止刪除操作。
const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true
  }
});

const Post = sequelize.define('Post', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true
  },
  userId: {
    type: DataTypes.INTEGER,
    references: {
      model: User,
      key: 'id'
    },
    onDelete: 'CASCADE' // 當關(guān)聯(lián)的 User 記錄被刪除時,與之關(guān)聯(lián)的 Post 記錄也將被刪除
  }
});

這里定義了一個 User 模型和一個 Post 模型。在 Post 模型的定義中,我們設(shè)置了與 User 模型的關(guān)聯(lián),并在 userId 屬性上使用了 onDelete: 'CASCADE' 選項。這意味著當與之關(guān)聯(lián)的 User 記錄被刪除時,與之關(guān)聯(lián)的 Post 記錄也將被級聯(lián)刪除。

onUpdate:更新關(guān)聯(lián)

onUpdate 是一個定義關(guān)聯(lián)關(guān)系時可以設(shè)置的選項之一。它用于指定當關(guān)聯(lián)模型的記錄被更新時要執(zhí)行的操作。

使用 onUpdate 選項,可以定義在更新關(guān)聯(lián)模型的記錄時應(yīng)該執(zhí)行的操作,例如級聯(lián)更新或什么都不做等。

以下是一些常用的 onUpdate 選項值及其含義:

  • CASCADE:級聯(lián)更新。當關(guān)聯(lián)模型的記錄被更新時,與之關(guān)聯(lián)的記錄也將相應(yīng)地進行更新。
  • SET NULL:設(shè)置為 null。當關(guān)聯(lián)模型的記錄被更新時,與之關(guān)聯(lián)的記錄的外鍵值將被設(shè)置為 null。
  • SET DEFAULT:設(shè)置為默認值。當關(guān)聯(lián)模型的記錄被更新時,與之關(guān)聯(lián)的記錄的外鍵值將被設(shè)置為默認值。
  • RESTRICT:限制。當關(guān)聯(lián)模型的記錄被更新時,如果有其他關(guān)聯(lián)記錄存在,則會阻止更新操作。
const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true
  }
});

const Post = sequelize.define('Post', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true
  },
  userId: {
    type: DataTypes.INTEGER,
    references: {
      model: User,
      key: 'id'
    },
    onUpdate: 'CASCADE' // 當關(guān)聯(lián)的 User 記錄被更新時,與之關(guān)聯(lián)的 Post 記錄也將被相應(yīng)地更新
  }
});

這里定義了一個 User 模型和一個 Post 模型。在 Post 模型的定義中,我們設(shè)置了與 User 模型的關(guān)聯(lián),并在 userId 屬性上使用了 onUpdate: 'CASCADE' 選項。這意味著當與之關(guān)聯(lián)的 User 記錄被更新時,與之關(guān)聯(lián)的 Post 記錄也將相應(yīng)地進行級聯(lián)更新。

模型繼承

模型繼承是一種將一個模型繼承自另一個模型的機制。這使得你可以從一個已有的模型中派生出新的模型,并繼承它的屬性、方法和關(guān)聯(lián)關(guān)系,從而實現(xiàn)代碼重用和模型的層次結(jié)構(gòu)組織。

模型繼承通過使用 sequelize.define() 方法的 options 參數(shù)來實現(xiàn)。在定義模型時,可以指定 options 參數(shù)中的 extend 屬性,來指定該模型繼承自哪個父模型。被繼承的父模型稱為基礎(chǔ)(或父)模型,而繼承的新模型稱為派生(或子)模型。

下面來看看如何在 Sequelize 中進行模型繼承:

const { Model, DataTypes } = require('sequelize');
const sequelize = new Sequelize('database', 'username', 'password');

// 定義基礎(chǔ)模型
const BaseModel = sequelize.define('base', {
  name: {
    type: DataTypes.STRING,
    allowNull: false,
  },
  // 其他屬性...
});

// 定義派生模型,并繼承基礎(chǔ)模型
const DerivedModel = sequelize.define('derived', {
  age: {
    type: DataTypes.INTEGER,
    allowNull: false,
  },
  // 其他屬性...
}, {
  extend: BaseModel,
});

// 創(chuàng)建派生模型的實例
DerivedModel.create({ name: 'John', age: 25 })
  .then((instance) => {
    console.log(instance.toJSON());
  })
  .catch(console.error);

這里首先定義了一個基礎(chǔ)模型 BaseModel,它有一個名為 name 的屬性。然后,定義了派生模型 DerivedModel,它繼承自基礎(chǔ)模型,并新增了一個名為 age 的屬性。最后,我們使用派生模型的 create() 方法創(chuàng)建一個新的實例,并輸出其序列化后的 JSON 數(shù)據(jù)。

通過模型繼承,可以在派生模型中重用和擴展基礎(chǔ)模型的屬性、方法和關(guān)聯(lián)關(guān)系,從而簡化代碼的編寫和維護。這對于構(gòu)建具有層次結(jié)構(gòu)的數(shù)據(jù)模型非常有用,例如用戶、管理員和超級管理員之間的繼承關(guān)系。

修改模型

在 Sequelize 中,修改、刪除已有字段或新增字段的過程如下:

  1. 在模型定義中進行相應(yīng)的更改。
  2. 使用 Sequelize 提供的遷移工具執(zhí)行數(shù)據(jù)庫遷移操作。

過程如下:

  1. 修改已有字段的數(shù)據(jù)類型和屬性:
// 修改已有字段的數(shù)據(jù)類型和屬性
await sequelize.queryInterface.changeColumn('User', 'age', {
  type: Sequelize.STRING,
  allowNull: true,
});
  1. 刪除已有字段:
// 刪除已有字段
await sequelize.queryInterface.removeColumn('User', 'age');
  1. 新增字段:
{
// 新增字段
await sequelize.queryInterface.addColumn('User', 'gender', {
  type: Sequelize.STRING,
  allowNull: true,
});

這里用 Sequelize 提供的 queryInterface 對象來執(zhí)行數(shù)據(jù)庫遷移操作。該對象提供了一系列方法來修改表結(jié)構(gòu)。

  • 對于修改已有字段,可以使用 changeColumn 方法指定要更改的模型名稱、字段名稱和新的屬性。
  • 對于刪除已有字段,可以使用 removeColumn 方法指定要刪除的模型名稱和字段名稱。
  • 對于新增字段,我們可以使用 addColumn 方法指定要新增字段的模型名稱、字段名稱和屬性。

在 Sequelize 中,修改模型定義并執(zhí)行相應(yīng)的遷移操作后,默認情況下數(shù)據(jù)庫表不會自動同步更改。你需要顯式地調(diào)用 sequelize.sync 方法來同步模型和數(shù)據(jù)庫表。以下是一個在執(zhí)行遷移操作后手動調(diào)用 sequelize.sync 方法的示例代碼:

// 執(zhí)行遷移操作...
// ...
// 手動同步模型和數(shù)據(jù)庫表
await sequelize.sync();

這里使用 await sequelize.sync() 方法手動同步模型和數(shù)據(jù)庫表。這將更新數(shù)據(jù)庫表結(jié)構(gòu)以匹配模型定義的更改。

注意,sequelize.sync() 方法會根據(jù)模型定義生成創(chuàng)建、修改或刪除表的 SQL 命令,然后將其應(yīng)用于數(shù)據(jù)庫。因此,請確保在生產(chǎn)環(huán)境中謹慎使用該方法,并提前備份重要的數(shù)據(jù)。

如果使用 Sequelize-CLI 或其他遷移工具來管理數(shù)據(jù)庫遷移,它們通常會自動處理模型與數(shù)據(jù)庫表的同步操作,你不需要手動調(diào)用 sequelize.sync() 方法。但如果你手動修改了模型定義或直接使用 queryInterface 修改數(shù)據(jù)庫表結(jié)構(gòu),則需要手動同步模型和數(shù)據(jù)庫表。

刪除模型

要刪除 Sequelize 中的模型,可以使用 sequelize.drop 方法。

以下是一個示例代碼來刪除一個名為 User 的模型:

// 刪除模型
await User.drop();

注意,刪除模型將會永久刪除數(shù)據(jù)庫表,包括其中的數(shù)據(jù)。在執(zhí)行模型刪除操作之前,請確保備份重要的數(shù)據(jù)。請謹慎操作刪除模型,確保你的操作不會導(dǎo)致數(shù)據(jù)丟失或不可逆的更改。

在異步函數(shù)中執(zhí)行刪除操作,并在完成后輸出相應(yīng)的信息。最后,記得關(guān)閉 Sequelize 連接,以避免資源泄漏。

模型查詢

先來看看查詢是一些通用查詢參數(shù)。

通用參數(shù)

where:查詢條件

使用 where 方法可以添加查詢條件,它可以用于查詢語句中的各種不同部分,如 findOne 和 findAll 等。通過 where 方法可以根據(jù)指定的條件過濾數(shù)據(jù)庫中的記錄。

Op 對象是 Sequelize 中用于定義各種操作符的對象。它提供了很多常用的操作符,可以在查詢條件中使用。以下是一些常見的 Op 屬性及其對應(yīng)的操作符:

  • Op.eq:等于
  • Op.ne:不等于
  • Op.gt:大于
  • Op.gte:大于等于
  • Op.lt:小于
  • Op.lte:小于等于
  • Op.like:模糊匹配
  • Op.notLike:不匹配
  • Op.iLike:忽略大小寫的模糊匹配
  • Op.notILike:忽略大小寫的不匹配
  • Op.in:在給定數(shù)組中的值
  • Op.notIn:不在給定數(shù)組中的值
  • Op.between:在給定范圍內(nèi)的值
  • Op.notBetween:不在給定范圍內(nèi)的值
等于
model.findAll({
  where: {
    age: 18
  }
});

上述代碼會查找 age 等于 18 的所有記錄。

不等于
model.findAll({
  where: {
    age: {[Op.ne]: 18}
  }
});

上述代碼會查找 age 不等于 18 的所有記錄。

大于
model.findAll({
  where: {
    age: {[Op.gt]: 18}
  }
});

上述代碼會查找 age 大于 18 的所有記錄。

小于
model.findAll({
  where: {
    age: {[Op.lt]: 18}
  }
});

上述代碼會查找 age 小于 18 的所有記錄。

大于等于
model.findAll({
  where: {
    age: {[Op.gte]: 18}
  }
});

上述代碼會查找 age 大于等于 18 的所有記錄。

小于等于
model.findAll({
  where: {
    age: {[Op.lte]: 18}
  }
});

上述代碼會查找 age 小于等于 18 的所有記錄。

模糊匹配
model.findAll({
  where: {
    name: {
      [Op.like]: '%John%'
    }
  }
});

上述代碼會查找 name 字段中包含 "John" 的所有記錄。

也可以使用 $like 來查詢,這是 sequelize 的舊語法,建議使用新語法 [Op.like] 來查詢:

model.findAll({
  where: {
    name: {
      $like: '%John%'
    }
  }
});
范圍
model.findAll({
  where: {
    age: {[Op.between]: [18, 30]}
  }
});

上述代碼會查找 age 在 18 到 30 之間的所有記錄。

子查詢

可以使用 [Op.or] 操作符來實現(xiàn)查詢一個字段等于 a 或 b 的操作。

const { Op } = require('sequelize');

const users = await User.findAll({
  where: {
    [Op.or]: [
      { name: 'a' },
      { name: 'b' },
    ],
  },
});

這里使用 findAll 方法查找所有名字等于 'a' 或 'b' 的用戶。其中,[Op.or] 表示 OR 連接操作符,將兩個條件拼接成 OR 條件。

注意,在實際使用時,如果需要查詢多個可能值,可以使用[Op.in]操作符,例如:

const users = await User.findAll({
  where: {
    name: {
      [Op.in]: ['a', 'b'],
    },
  },
});

上述代碼將會查詢所有名字等于 'a' 或 'b' 的用戶。

include:包含關(guān)聯(lián)模型

在 Sequelize 中,可以使用關(guān)聯(lián)來定義模型之間的關(guān)系,例如一對一、一對多或多對多關(guān)系。當查詢模型時,如果希望返回與該模型關(guān)聯(lián)的其他模型的屬性,就需要使用 include 選項來包含關(guān)聯(lián)模型。可以根據(jù)需要輕松地從其他模型中獲取相關(guān)數(shù)據(jù),而無需單獨進行額外的查詢操作。

User.findAll({
  include: {
    model: Post,
    attributes: ['title', 'content']
  }
})
  .then((users) => {
    // 處理查詢結(jié)果
    users.forEach((user) => {
      console.log('用戶名:', user.name);
      console.log('用戶發(fā)布的文章:');
      user.Posts.forEach((post) => {
        console.log('標題:', post.title);
        console.log('內(nèi)容:', post.content);
      });
    });
  })
  .catch((error) => {
    // 處理查詢錯誤
  });

這里使用 User 模型進行查詢,通過 include 選項包含了關(guān)聯(lián)的 Post 模型。然后,在 .then 回調(diào)函數(shù)中處理查詢結(jié)果。每個用戶對象都包含了他們的相關(guān)文章數(shù)據(jù),可以通過訪問 user.Posts 屬性來獲取關(guān)聯(lián)的文章數(shù)據(jù)。

當在主模型上執(zhí)行查詢后,包含關(guān)聯(lián)模型的查詢實際上是在主模型查詢的基礎(chǔ)上進行的。

首先,使用主模型進行查詢,獲取與查詢條件匹配的主模型數(shù)據(jù)。然后,在查詢結(jié)果中包含的每個主模型實例上,Sequelize 將自動執(zhí)行額外的查詢來獲取與之關(guān)聯(lián)的其他模型的數(shù)據(jù)。

這種查詢方式稱為延遲加載或延遲關(guān)聯(lián)。它的優(yōu)點是只有在需要訪問關(guān)聯(lián)模型數(shù)據(jù)時才執(zhí)行額外的查詢,避免了不必要的查詢開銷。

在上面的示例中,當調(diào)用 User.findAll() 查詢用戶時,Sequelize 會從數(shù)據(jù)庫獲取與查詢條件匹配的用戶數(shù)據(jù)。然后,當訪問 user.Posts 屬性時,Sequelize 會自動執(zhí)行另一個查詢來獲取該用戶關(guān)聯(lián)的文章數(shù)據(jù)。

在查詢時包含多個關(guān)聯(lián)模型,可以通過 Sequelize 的 include 選項的不同方式來實現(xiàn)。下面有兩種常用的方法:

  1. 使用數(shù)組形式包含多個關(guān)聯(lián)模型:
User.findAll({
  include: [
    { model: Profile },
    { model: Post }
  ]
})
  .then((users) => {
    // 處理查詢結(jié)果
    users.forEach((user) => {
      console.log('用戶名:', user.name);
      console.log('用戶配置:', user.Profile);
      console.log('用戶文章:', user.Posts);
    });
  })
  .catch((error) => {
    // 處理查詢錯誤
  });

在上述代碼中,將要包含的關(guān)聯(lián)模型作為對象放入數(shù)組中,并將該數(shù)組作為 include 選項的值。這樣,在查詢結(jié)果中就會包含多個關(guān)聯(lián)模型的數(shù)據(jù)。

  1. 嵌套方式包含多個關(guān)聯(lián)模型:
User.findAll({
  include: [
    { 
      model: Profile,
      include: [Category]  // 在 Profile 模型中嵌套包含 Category 模型
    },
    { model: Post }
  ]
})
  .then((users) => {
    // 處理查詢結(jié)果
    users.forEach((user) => {
      console.log('用戶名:', user.name);
      console.log('用戶配置:', user.Profile);
      console.log('用戶文章:', user.Posts);
      console.log('用戶配置的類別:', user.Profile.Category);
    });
  })
  .catch((error) => {
    // 處理查詢錯誤
  });

這里使用嵌套的方式,在其中一個關(guān)聯(lián)模型的 include 選項中,再嵌套包含另一個關(guān)聯(lián)模型。這樣可以實現(xiàn)更深層次的關(guān)聯(lián)查詢。

通過以上方式,可以在查詢時包含多個關(guān)聯(lián)模型,并獲取它們的數(shù)據(jù)。根據(jù)需求和模型之間的關(guān)系,可以靈活地組合和嵌套使用 include 選項來包含多個關(guān)聯(lián)模型。

注意:只有在模型定義中定義了關(guān)聯(lián)關(guān)系,才能在查詢時包含關(guān)聯(lián)模型。

attributes:返回字段

可以使用 attributes 選項指定要返回的字段。示例:attributes: ['id', 'name']。它用于控制查詢結(jié)果中包含哪些屬性或排除哪些屬性,可以接受多種形式的參數(shù),以控制返回的屬性。

以下是幾種常見的 attributes 選項的用法:

  • 字符串數(shù)組:可以傳入一個字符串數(shù)組,表示要返回的屬性名。示例:attributes: ['name', 'age'],表示查詢結(jié)果將僅包含 'name' 和 'age' 兩個字段。
  • 嵌套對象:可以傳入一個嵌套對象,用于更復(fù)雜的字段控制。示例:attributes: { include: ['name'], exclude: ['age'] },表示查詢結(jié)果將包含 name 字段,并排除 age 字段。
  • 聚合函數(shù):可以使用聚合函數(shù)對屬性進行計算,并將計算結(jié)果命名為新的屬性。示例:attributes: [[sequelize.fn('SUM', sequelize.col('quantity')), 'totalQuantity']],表示查詢結(jié)果中將返回一個計算總和的聚合函數(shù),并將計算結(jié)果命名為totalQuantity。

注意事項:

  • 如果不指定 attributes 選項,默認情況下會返回所有模型的屬性;指定了 attributes 選項后,只會返回指定的屬性。
  • 使用 attributes 選項時,如果要返回關(guān)聯(lián)模型的屬性,需要在關(guān)聯(lián)模型上設(shè)置 include 選項。
order:排序規(guī)則

可以使用 order 選項來指定返回結(jié)果的排序規(guī)則。示例:order: [['createdAt', 'DESC']],它表示按照 createdAt 字段進行降序排列。

在 Sequelize 中,可以通過 order 選項來指定查詢結(jié)果的排序規(guī)則。排序規(guī)則由一個二維數(shù)組表示,每個子數(shù)組包含兩個元素:排序字段和排序方式。排序字段可以是模型的屬性名或關(guān)聯(lián)模型的屬性名。排序方式可以是 'ASC'(升序)或 'DESC'(降序)。

以下是order 選項常見的用法:

  • 單字段排序:可以只指定一個排序字段和排序方式。示例:order: [['fieldName', 'ASC']]。
  • 多字段排序:可以指定多個排序字段和排序方式,按照指定的順序依次排序。示例:order: [['field1', 'ASC'], ['field2', 'DESC']]。
  • 關(guān)聯(lián)模型排序:可以使用關(guān)聯(lián)模型的屬性進行排序。示例:order: [['RelatedModel', 'fieldName', 'ASC']]。

注意事項:

  • 排序字段必須是模型或關(guān)聯(lián)模型的屬性名。
  • 排序方式應(yīng)為 'ASC' 或 'DESC'。
  • 在查詢語句中使用多個排序條件時,將按照指定的順序依次應(yīng)用這些條件。
Model.findOne({
  where: {
    // 查詢條件
    status: 'active'
  },
  order: [['createdAt', 'DESC']]
})
  .then((records) => {
    // 處理查詢結(jié)果
  })
  .catch((error) => {
    // 處理查詢錯誤
  })

這里使用了 order 選項,通過 [['createdAt', 'DESC']] 指定了按照 createdAt 字段進行降序排列。

limit:查詢結(jié)果的數(shù)量

用于限制查詢結(jié)果返回的記錄數(shù)量,常用于分頁查詢。

Model.findAll({
  limit: 10  // 返回最多 10 條記錄
})
  .then((results) => {
    // 處理查詢結(jié)果
  })
  .catch((error) => {
    // 處理查詢錯誤
  });
offset:查詢結(jié)果的偏移量

用于設(shè)置查詢結(jié)果的偏移量,從指定位置開始返回結(jié)果,常用于分頁查詢。這個偏移量是基于索引的,而索引是從零開始計數(shù)的。

Model.findAll({
  offset: 5  // 忽略前 5 條記錄
})
  .then((results) => {
    // 處理查詢結(jié)果
  })
  .catch((error) => {
    // 處理查詢錯誤
  });
group:結(jié)果分組

用于對結(jié)果進行分組:按照指定的字段值進行分類歸納,將具有相同字段值的記錄放在一組中。

Model.findAll({
  attributes: ['age'],
  group: ['age']
})
  .then((results) => {
    // 處理查詢結(jié)果
    results.forEach((group) => {
      console.log('分組:');
      group.forEach((record) => {
        console.log('記錄:', record);
      });
    });
  })
  .catch((error) => {
    // 處理查詢錯誤
  });

這里使用 group 選項對 age 字段進行分組。查詢結(jié)果 results 是一個數(shù)組,其中每個元素代表一個分組。對于每個分組,可以遍歷內(nèi)層數(shù)組 group,其中的每個元素代表該分組中的一條記錄。

distinct:結(jié)果去重

當設(shè)置 distinct: true 時,查詢結(jié)果將會返回去重后的記錄。這在某些情況下非常有用,例如獲取一個字段的唯一值列表或者按照某個字段進行分組統(tǒng)計時。

這里使用 distinct: true 設(shè)置查詢結(jié)果為去重模式,并指定了要查詢的字段為 name。查詢結(jié)果將只包含去重后的姓名列表。

例如,假設(shè)有一個名為 User 的模型,并且希望獲取所有不重復(fù)的用戶名:

const users = await User.findAll({
  attributes: ['name'],
  distinct: true
});

這里通過設(shè)置 distinct: true 來確保只返回不重復(fù)的用戶名。查詢結(jié)果將只包含唯一的、不重復(fù)的用戶名。

注意,distinct 選項必須與指定的查詢字段一起使用,確保只對指定的字段進行去重操作。

findOne:查詢第一條

查詢符合條件的第一條記錄。

Model.findOne({
  where: {
    // 查詢條件
    id: 1
  }
})
  .then((record) => {
    if (record) {
      console.log('查詢到的記錄:', record.get({ plain: true }));
    } else {
      console.log('未找到符合條件的記錄');
    }
  })
  .catch((error) => {
    // 處理查詢錯誤
  });

這個方法的返回值是一個 Sequelize Model 對象,其中包含與記錄相關(guān)聯(lián)的屬性、方法和關(guān)系。它具有以下特性:

  • 屬性訪問:可以通過屬性名直接訪問記錄的字段值,例如 record.fieldName。
  • 數(shù)據(jù)獲?。嚎梢允褂?nbsp;.get() 方法獲取包含所有字段的對象形式的記錄數(shù)據(jù),例如 record.get(),其用法如下。

record.get():返回一個包含所有字段的對象,其中字段名作為鍵,字段值作為值。這個對象是 Sequelize 模型實例,包含與記錄相關(guān)聯(lián)的屬性和方法。

record.get({ plain: true }):返回一個純對象,只包含記錄的原始字段和值,不包含與 Sequelize 相關(guān)的屬性和方法。

獲取指定字段的值:可以傳遞一個或多個字段名作為參數(shù),獲取特定字段的值。示例:record.get('fieldName') 或 record.get('field1', 'field2')。

排除指定字段:可以使用 { exclude: ['fieldName'] } 選項來排除指定的字段,獲取除這些字段外的其他字段。示例:record.get({ exclude: ['fieldName'] })。

只獲取指定字段:可以使用 { attributes: ['fieldName'] } 選項來只獲取指定的字段。示例:record.get({ attributes: ['fieldName'] })。

Model.findOne({
  where: {
    // 查詢條件
    id: 1
  }
})
  .then((record) => {
    if (record) {
      const fieldValue = record.get('fieldName');
      console.log('字段值:', fieldValue);
      
      const excludedData = record.get({ exclude: ['field1', 'field2'] });
      console.log('排除字段后的數(shù)據(jù):', excludedData);
      
      const selectedData = record.get({ attributes: ['field1', 'field2'] });
      console.log('只包含指定字段的數(shù)據(jù):', selectedData);
    } else {
      console.log('未找到符合條件的記錄');
    }
  })
  .catch((error) => {
    // 處理查詢錯誤
  });

注意,Model.findOne 方法只返回滿足查詢條件的第一條記錄。如果沒有符合條件的記錄,則返回 null。

另外,distinct: true 在某些數(shù)據(jù)庫管理系統(tǒng)中可能會導(dǎo)致性能下降,因為它需要進行更多的計算來實現(xiàn)去重。所以在使用 distinct: true 時,要謹慎考慮其對性能的影響。

findAll:查詢?nèi)?/h3>

sequelize.findAll() 用于從數(shù)據(jù)庫中檢索所有匹配給定條件的記錄。它的語法如下:

Model.findAll({
  attributes: [], // 要選擇的屬性列表,默認為所有屬性
  where: {}, // 過濾條件
  include: [], // 關(guān)聯(lián)模型
  order: [], // 排序規(guī)則
  limit: 0, // 返回的最大記錄數(shù),默認為0(返回所有記錄)
  offset: 0, // 結(jié)果集的起始偏移量,默認為0
});

參數(shù)說明:

  • attributes:指定要選擇的屬性列表,如果為空,則返回所有屬性。
  • where:指定過濾條件,可以使用各種條件運算符(如等于、不等于、大于、小于等)來篩選記錄。
  • include:指定要關(guān)聯(lián)的其他模型,可以進行關(guān)聯(lián)查詢。
  • order:指定結(jié)果集的排序規(guī)則。
  • limit:指定要返回的最大記錄數(shù),默認為0,表示返回所有符合條件的記錄。
  • offset:指定結(jié)果集的起始偏移量,默認為0。

這個方法將返回一個Promise,當查詢成功時,Promise將解析為包含所有符合條件的記錄的數(shù)組。以下是一個示例:

Model.findAll({
  where: {
    // 查詢條件
    status: 'active'
  }
})
  .then((records) => {
    if (records.length > 0) {
      console.log('查詢到的記錄數(shù):', records.length);
      
      records.forEach((record) => {
        const data = record.get();
        console.log('記錄數(shù)據(jù):', data);
      });
    } else {
      console.log('未找到符合條件的記錄');
    }
  })
  .catch((error) => {
    // 處理查詢錯誤
  });

注意,如果沒有查詢到符合條件的記錄,返回的數(shù)組將為空。

findByPk:根據(jù)主鍵值查詢

根據(jù)主鍵值查詢記錄,它的語法如下:

Model.findByPk(id, options);

參數(shù)說明:

  • id:要查詢的記錄的主鍵值。
  • options:可選參數(shù),用于指定進一步的配置,比如關(guān)聯(lián)模型等。

下面來看一個例子,通過主鍵值來獲取特定的用戶記錄:

const user = await User.findByPk(1);
console.log(user);

上述代碼將查詢主鍵值為 1 的用戶記錄,并將結(jié)果保存在 user 變量中。如果找到匹配的記錄,則 user 將是一個包含該記錄的對象。否則,user 將是 null。

如果要通過主鍵值獲取多個記錄,可以傳入一個數(shù)組作為 id 參數(shù),如:

const users = await User.findByPk([1, 2, 3]);
console.log(users);

上述代碼將查詢主鍵值為 1、2 和 3 的用戶記錄,并將結(jié)果保存在 users 變量中,它將是一個包含這些記錄的數(shù)組。

findByPk 也可以與其他查詢配置選項一起使用,例如關(guān)聯(lián)模型、選擇屬性等??梢栽?nbsp;options 參數(shù)中指定這些額外的配置選項。

注意:findByPk 方法返回一個 Promise,在查詢成功時解析為匹配的記錄(或記錄數(shù)組),在查詢失敗時拒絕為錯誤對象。因此,需要使用 await 或 .then() 來處理查詢結(jié)果或捕獲錯誤。

在 Sequelize 中,主鍵值是指用于唯一標識數(shù)據(jù)庫表中每個記錄的列或?qū)傩?。主鍵值在表中具有唯一性,沒有重復(fù)的值,且不能為空。在 Sequelize 模型定義中,可以通過 primaryKey: true 來將某個屬性指定為主鍵。例如:

const User = sequelize.define('User', {
  id: {
    type: DataTypes.INTEGER,
    primaryKey: true,
    autoIncrement: true
  },
  name: DataTypes.STRING,
  email: DataTypes.STRING
});

在上述例子中,id 屬性被指定為主鍵。它的類型為整數(shù)(INTEGER),并且設(shè)置了 primaryKey: true 表示該屬性是主鍵。此外,還可以使用 autoIncrement: true 來指定該主鍵自動增長,以便在插入新記錄時自動生成唯一的主鍵值。

當使用 findByPk、update、destroy 等方法時,通常會使用主鍵值來準確定位要操作的記錄。通過提供正確的主鍵值,Sequelize 可以根據(jù)主鍵來查詢、更新或刪除相應(yīng)的記錄。

findOrCreate:查詢或創(chuàng)建

findOrCreate 用于根據(jù)指定條件查找數(shù)據(jù)庫中的記錄,如果找到匹配的記錄,則返回該記錄;如果找不到匹配的記錄,則創(chuàng)建一個新的記錄并返回。它的語法如下:

Model.findOrCreate({
  where: { ... },
  defaults: { ... },
  ...
});

參數(shù)說明:

  • where:包含查找條件的對象,用于指定要匹配的屬性和值。
  • defaults:包含要創(chuàng)建新記錄時的默認值的對象。
  • ...:其他可選參數(shù),用于進一步配置查詢。

使用 findOrCreate 方法時,Sequelize 首先根據(jù) where 條件嘗試在數(shù)據(jù)庫中查找符合條件的記錄。如果找到匹配的記錄,則返回該記錄作為結(jié)果。

如果沒有找到匹配的記錄,則使用 defaults 指定的默認值創(chuàng)建一個新的記錄,并返回該新記錄作為結(jié)果。默認值將應(yīng)用于新創(chuàng)建的記錄的屬性。

例如,假設(shè)有一個名為 User 的模型表示用戶表,其中 email 是唯一的:

const User = sequelize.define('User', {
  name: DataTypes.STRING,
  email: {
    type: DataTypes.STRING,
    unique: true
  }
});

現(xiàn)在想根據(jù)郵箱查找用戶記錄,如果找到則返回該記錄,如果找不到則創(chuàng)建一個新用戶記錄??梢允褂?nbsp;findOrCreate 方法:

const [user, created] = await User.findOrCreate({
  where: { email: 'example@example.com' },
  defaults: { name: 'John Doe' }
});

console.log(user); // 匹配的記錄或新創(chuàng)建的記錄
console.log(created); // 表示是否新創(chuàng)建了記錄的布爾值

上述代碼將根據(jù)指定的郵箱查找用戶記錄,如果找到匹配的記錄,則返回該記錄。如果沒有找到匹配的記錄,則創(chuàng)建一個新的記錄,并返回新創(chuàng)建的記錄。

findOrCreate 方法返回一個包含兩個元素的數(shù)組:第一個元素是匹配的記錄(已存在或新創(chuàng)建),第二個元素是一個布爾值,表示是否新創(chuàng)建了記錄。

如果有多個符合條件的記錄,findOrCreate 方法僅返回匹配的第一個記錄。它不會返回所有符合條件的記錄。

findAndCountAll:查詢記錄和數(shù)量

findAndCountAll 用于查找滿足指定條件的所有記錄,并返回滿足條件的記錄數(shù)組和記錄總數(shù)。它的語法如下:

Model.findAndCountAll({
  where: { ... },
  include: [ ... ],
  offset: ...,
  limit: ...,
  order: [...],
  ...
});

參數(shù)說明:

  • where:包含查找條件的對象,用于指定要匹配的屬性和值。
  • include:指定關(guān)聯(lián)模型,用于在查詢中包含關(guān)聯(lián)的數(shù)據(jù)。
  • offset:指定查詢的偏移量,用于分頁。
  • limit:指定查詢的限制數(shù)量,用于分頁。
  • order:指定查詢結(jié)果的排序順序。
  • ...:其他可選參數(shù),用于進一步配置查詢。

使用 findAndCountAll 方法時,Sequelize 將根據(jù)指定的條件在數(shù)據(jù)庫中查找符合條件的所有記錄,并同時返回滿足條件的記錄數(shù)組和記錄總數(shù)。

const { count, rows } = await User.findAndCountAll({
  where: { age: 25 },
  include: [Post],
  offset: 0,
  limit: 10,
  order: [['createdAt', 'DESC']]
});

console.log(count); // 符合條件的記錄總數(shù)
console.log(rows); // 符合條件的記錄數(shù)組

在上述代碼中,findAndCountAll 方法將根據(jù)年齡為 25 的條件在數(shù)據(jù)庫中查找用戶記錄,并返回滿足條件的記錄總數(shù)和記錄數(shù)組。include 參數(shù)用于指定要關(guān)聯(lián)的 Post 模型。

findAndCountAll 方法返回的結(jié)果是一個包含 count 和 rows 屬性的對象。count 表示符合條件的記錄總數(shù),rows 表示符合條件的記錄數(shù)組。

使用 findAndCountAll 方法可以方便地獲取滿足條件的記錄總數(shù)以及相應(yīng)的記錄數(shù)組,用于實現(xiàn)分頁和其他結(jié)果統(tǒng)計的需求。

count:查詢數(shù)量

可以使用 count 方法來獲取滿足指定條件的記錄數(shù)。它的語法如下:

Model.count({
  where: { ... },
  ...
});

參數(shù)說明:

  • where:包含查找條件的對象,用于指定要匹配的屬性和值。
  • ...:其他可選參數(shù),用于進一步配置查詢。

使用 count 方法時,Sequelize 將根據(jù)指定的條件在數(shù)據(jù)庫中計算符合條件的記錄數(shù),并返回該記錄數(shù)。

const count = await User.count({
  where: { age: 25 }
});

console.log(count); // 符合條件的記錄數(shù)

在上述代碼中,count 方法將根據(jù)年齡為 25 的條件在數(shù)據(jù)庫中計算符合條件的用戶記錄數(shù),并將其返回。該方法返回的結(jié)果將是一個表示符合條件的記錄數(shù)的整數(shù)值。

通過使用 count 方法,可以方便地獲取滿足條件的記錄數(shù),用于進行結(jié)果統(tǒng)計、分頁計算或其他相關(guān)處理。

min, max, sum:查詢最值

可以使用 min、max 和 sum 方法來進行最小值、最大值和求和計算。

這些方法可以通過調(diào)用模型的靜態(tài)方法來實現(xiàn),具體語法如下:

  1. min 方法用于計算指定屬性列的最小值:
Model.min('column', {
  where: { ... },
  ...
});
  1. max 方法用于計算指定屬性列的最大值:
Model.max('column', {
  where: { ... },
  ...
});
  1. sum 方法用于計算指定屬性列的總和:
Model.sum('column', {
  where: { ... },
  ...
});

參數(shù)說明:

  • 'column':要進行計算的屬性列的名稱。
  • where:包含查找條件的對象,用于指定要匹配的屬性和值。
  • ...:其他可選參數(shù),用于進一步配置查詢。
const minValue = await Model.min('column', {
  where: { ... }
});

const maxValue = await Model.max('column', {
  where: { ... }
});

const sumValue = await Model.sum('column', {
  where: { ... }
});

console.log(minValue); // 最小值
console.log(maxValue); // 最大值
console.log(sumValue); // 總和

注意,這些方法將返回一個 Promise 對象,需要使用 await 或 .then() 來獲取計算結(jié)果。

create:創(chuàng)建數(shù)據(jù)

create() 方法用于在數(shù)據(jù)庫中創(chuàng)建一個新的記錄。它是 Sequelize 模型的一個實例方法,可以通過模型對象調(diào)用。

const newUser = await User.create({
  name: 'John Doe',
  email: 'john.doe@example.com',
  age: 25,
});

使用 User.create() 方法創(chuàng)建一個名為 User 的新記錄。通過傳遞一個包含屬性和值的對象參數(shù),指定要創(chuàng)建的記錄的字段值。調(diào)用 create()方法會將新記錄插入到與模型關(guān)聯(lián)的數(shù)據(jù)庫表中,并返回一個表示新記錄的模型實例。

注意,create() 方法返回的是一個 Promise 對象,因此可以使用 await 關(guān)鍵字來等待創(chuàng)建操作的結(jié)果。如果創(chuàng)建成功,將返回包含新記錄數(shù)據(jù)的模型實例;如果創(chuàng)建失敗,將拋出一個異常。

create() 方法可以用于創(chuàng)建單個記錄,也可以用于批量創(chuàng)建多條記錄。如果想要批量創(chuàng)建多條記錄,可以將一個包含多個對象的數(shù)組傳遞給 create() 方法。

const newUsers = await User.create([
  {
    name: 'John Doe',
    email: 'john.doe@example.com',
    age: 25,
  },
  {
    name: 'Jane Smith',
    email: 'jane.smith@example.com',
    age: 30,
  },
]);

bulkCreate:批量創(chuàng)建數(shù)據(jù)

要批量添加數(shù)據(jù),可以使用 Model.bulkCreate() 方法。bulkCreate() 方法接受一個數(shù)組作為參數(shù),每個數(shù)組元素都表示要創(chuàng)建的記錄。

const newUsers = await User.bulkCreate([
  {
    name: 'John Doe',
    email: 'john.doe@example.com',
    age: 25,
  },
  {
    name: 'Jane Smith',
    email: 'jane.smith@example.com',
    age: 30,
  },
  // 可以繼續(xù)添加更多對象...
]);

這里定義了一個 users 數(shù)組,其中包含要添加到數(shù)據(jù)庫的多個對象,每個對象表示一條記錄。然后,調(diào)用 User.bulkCreate() 方法,并傳遞 users 數(shù)組作為參數(shù),以批量添加這些記錄。

bulkCreate() 方法將會將數(shù)組中的每個對象插入到與模型關(guān)聯(lián)的數(shù)據(jù)庫表中,并返回一個包含新記錄的模型實例數(shù)組??梢愿鶕?jù)實際需求在 users 數(shù)組中添加任意數(shù)量的對象,以批量添加相應(yīng)數(shù)量的記錄。

bulkCreate() 和 create() 方法都可以用于創(chuàng)建多條數(shù)據(jù),但它們之間有一些區(qū)別:

  1. 性能差異:
  • create() 方法在循環(huán)中逐個創(chuàng)建記錄,并執(zhí)行多個數(shù)據(jù)庫查詢操作。這意味著對于大量數(shù)據(jù)的批量創(chuàng)建,性能可能較低。
  • bulkCreate() 方法會將所有記錄作為一個事務(wù)一次性插入數(shù)據(jù)庫,減少了數(shù)據(jù)庫查詢操作的次數(shù),因此在處理大量數(shù)據(jù)時可以更高效。
  1. 錯誤處理:
  • create() 方法是可回滾的,即如果在循環(huán)中創(chuàng)建多個記錄時發(fā)生錯誤,可以選擇回滾已創(chuàng)建的記錄。
  • bulkCreate() 方法默認情況下是不可回滾的,即如果在批量插入過程中發(fā)生錯誤,已插入的記錄將被保留。但你可以通過設(shè)置 individualHooks: true 選項來啟用回滾功能。
  1. 返回值:
  • create() 方法在成功創(chuàng)建每條記錄后,返回一個表示該記錄的模型實例。
  • bulkCreate() 方法在成功插入所有記錄后,返回一個包含所有新記錄的模型實例數(shù)組。

綜上所述,對于需要創(chuàng)建大量數(shù)據(jù)的情況,推薦使用 bulkCreate() 方法,以獲得更好的性能。但在某些情況下,例如需要在每次創(chuàng)建記錄時進行自定義操作或錯誤處理時,可以選擇使用 create() 方法。

update:更新數(shù)據(jù)

可以使用 update 方法來更新數(shù)據(jù)庫中的記錄。它的語法如下:

Model.update(values, {
  where: { ... },
  ...
});

參數(shù)說明:

  • values:一個包含要更新的屬性和值的對象。
  • where:一個包含更新條件的對象,用于指定要匹配的屬性和值。
  • ...:其他可選參數(shù),用于進一步配置更新。

使用 update 方法時,Sequelize 將根據(jù)指定的條件在數(shù)據(jù)庫中查找符合條件的記錄,并將相應(yīng)的屬性更新為指定的新值。

const result = await User.update(
  { age: 30, status: 'active' },
  {
    where: { id: 1 }
  }
);

console.log(result); // 更新結(jié)果

在上述代碼中,update 方法將會將 id 屬性為 1 的用戶記錄的 age 和 status 屬性更新為新的值。

注意,update 方法返回一個表示更新結(jié)果的數(shù)組。該數(shù)組的第一個元素表示更新的行數(shù),第二個元素表示影響的行數(shù)。

const updatedRows = result[0];
const affectedRows = result[1];

console.log(updatedRows); // 更新的行數(shù)
console.log(affectedRows); // 影響的行數(shù)

通過使用 update 方法,可以方便地更新滿足條件的記錄,并可以靈活配置要更新的屬性和值。

注意,update 方法只能更新單條記錄。如果想要更新多條數(shù)據(jù),可以借助 Promise.all 來實現(xiàn):

// 查找需要更新的數(shù)據(jù)
const usersToUpdate = await User.findAll({ where: { status: 'active' } });

// 更新數(shù)據(jù)
await Promise.all(usersToUpdate.map(user => {
  return user.update(
    { status: 'inactive' } // 更新的字段和值
  );
}));

destroy:刪除數(shù)據(jù)

在 Sequelize 中,可以使用 destroy 方法來刪除數(shù)據(jù)庫中的記錄。它的語法如下:

Model.destroy({
  where: { ... },
  ...
});

參數(shù)說明:

  • where:包含刪除條件的對象,用于指定要匹配的屬性和值。
  • ...:其他可選參數(shù),用于進一步配置刪除操作。

使用 destroy 方法時,Sequelize 將根據(jù)指定的條件在數(shù)據(jù)庫中查找符合條件的記錄,并將其從數(shù)據(jù)庫中刪除。

const result = await User.destroy({
  where: { id: 1 }
});

console.log(result); // 刪除結(jié)果

在上述代碼中,destroy 方法將會刪除數(shù)據(jù)庫中 id 屬性為 1 的用戶記錄。該方法返回一個表示刪除結(jié)果的整數(shù)值。該值表示成功刪除的記錄數(shù)。

destroy 方法可以刪除滿足多個條件的記錄,從而批量刪除數(shù)據(jù)庫中的多個值。

const result = await User.destroy({
  where: {
    age: { [Op.gt]: 30 },  // 年齡大于30
    status: 'inactive'     // 狀態(tài)為inactive
  }
});

console.log(result); // 刪除結(jié)果

上述代碼將會刪除數(shù)據(jù)庫中年齡大于30且狀態(tài)為inactive的用戶記錄。

模型聚合

模型聚合指的是使用 Sequelize 模型來執(zhí)行數(shù)據(jù)庫查詢,并對查詢結(jié)果進行聚合操作。通過使用 Sequelize 模型的聚合功能,你可以靈活地執(zhí)行各種統(tǒng)計和計算操作,并從數(shù)據(jù)庫中獲取所需的聚合結(jié)果。

模型聚合通常用于在查詢中應(yīng)用聚合函數(shù),以獲取關(guān)于數(shù)據(jù)集的匯總信息。聚合函數(shù)可以是內(nèi)置的數(shù)據(jù)庫函數(shù),也可以是自定義的函數(shù)。常見的聚合函數(shù)包括 SUM、COUNT、AVG、MAX、MIN 等。

假設(shè)有一個 Product 模型,它表示產(chǎn)品表。每個產(chǎn)品都有一個 price 字段,表示產(chǎn)品的價格?,F(xiàn)在,想計算所有產(chǎn)品的平均價格??梢允褂?Sequelize 的模型聚合功能來實現(xiàn):

const { fn, col } = require('sequelize');

const result = await Product.findOne({
  attributes: [
    [fn('AVG', col('price')), 'avgPrice']
  ]
});

這里使用 Product.findOne 查詢單個產(chǎn)品,并使用 attributes 參數(shù)指定要選擇的屬性列。我們使用 sequelize.fn 和 sequelize.col 創(chuàng)建了一個新的屬性列,將其命名為 avgPrice,并應(yīng)用了 AVG 聚合函數(shù)來計算價格的平均值。查詢結(jié)果將包含產(chǎn)品價格的平均值,以及對應(yīng)的屬性名稱。

注意,通過使用 sequelize.fn 和 sequelize.col,可以在查詢結(jié)果中創(chuàng)建一個虛擬的屬性列,用于存儲聚合函數(shù)計算得出的值(例如平均值、總和等)。這個虛擬字段只存在于查詢結(jié)果中,而不會對數(shù)據(jù)庫中的數(shù)據(jù)產(chǎn)生影響。換句話說,當執(zhí)行查詢并獲取結(jié)果時,每條結(jié)果將包含從數(shù)據(jù)庫中選擇的實際屬性列以及計算得出的虛擬屬性列(例如 avgPrice)。這些虛擬屬性僅在查詢結(jié)果中可見,不會直接影響數(shù)據(jù)庫中的數(shù)據(jù)。

sequelize.fn

sequelize.fn 是 Sequelize 提供的一個函數(shù),用于生成聚合函數(shù)的 SQL 片段。使用 sequelize.fn,可以在查詢中使用所有支持的聚合函數(shù)(如 COUNT、SUM、AVG、MIN、MAX 等)。

sequelize.fn 的語法如下:

sequelize.fn(functionName, args)

其中,functionName 是要調(diào)用的聚合函數(shù)名稱,如 COUNT、SUM、AVG、MIN、MAX 等;args 是可選的函數(shù)參數(shù),可以是列名稱或常量值。

sequelize.fn 可以與 sequelize.col 一起使用,用于生成復(fù)雜的 SQL 片段和查詢語句。它還可以與 where、group、having、order 等查詢選項一起使用。

sequelize.col

sequelize.col 用于生成對數(shù)據(jù)庫表中列的引用,使用 sequelize.col可以在查詢中引用特定的列。

sequelize.col 的語法如下:

sequelize.col(columnName)

其中,columnName 是要引用的列名稱。它可以是字符串形式的列名,也可以是一個包含表名和列名的數(shù)組。

下面使用 sequelize.col 引用 products 表中的 price 列:

const { col } = require('sequelize');

Product.findAll({
  attributes: [
    [col('price'), 'productPrice']
  ]
});

這里使用了 col 函數(shù)來生成一個對 price 列的引用,并將其映射到一個名為 productPrice 的屬性上。這樣,查詢結(jié)果中就會包含一個帶有別名的新屬性,它的值是 price 列的值。

屬性別名

[col('price'), 'productPrice'] 用于在查詢中定義屬性別名。它使用了數(shù)組的形式來表示一個屬性,并包含兩個元素:引用列的表達式和屬性別名。在這個例子中,col('price') 是一個 sequelize.col 函數(shù)調(diào)用,表示對 price 列的引用。'productPrice' 是一個字符串,表示希望將 price 列的值映射到一個名為 productPrice 的屬性上。這樣,返回的結(jié)果將會包含一個名為 productPrice 的屬性,其中的值是對應(yīng)的 price 列的值。

選擇所有列

col('*') 表示引用表中的所有列。通常,在 Sequelize 中,我們可以在 attributes 數(shù)組中使用它來選擇查詢結(jié)果中要返回的列。

const { col } = require('sequelize');

Product.findAll({
  attributes: [
    col('*')
  ]
});

這里使用 col('*') 來引用所有列。這意味著查詢結(jié)果將包含表中的每個列。

請注意,使用 col('*') 將返回表中的所有列,包括主鍵、外鍵和其他所有列。如果只想選擇特定的列,可以將列名以字符串的形式傳遞給 col 函數(shù),如 col('columnName')。

sequelize.literal

在 Sequelize 中,可以使用 sequelize.literal 方法來自定義聚合函數(shù)或任何其他數(shù)據(jù)庫原生函數(shù)。

sequelize.literal 允許在查詢中添加原始的 SQL 代碼,包括自定義的聚合函數(shù)??梢酝ㄟ^將 SQL 代碼作為字符串傳遞給 sequelize.literal 來實現(xiàn)。

下面來使用 sequelize.literal 自定義一個名為 customCount 的聚合函數(shù):

const { literal } = require('sequelize');

Product.findAll({
  attributes: [
    [literal('COUNT(*) + 1'), 'customCount']
  ]
});

這里使用了 literal 函數(shù)來生成一個原始的 SQL 表達式 COUNT(*) + 1,并將其映射到一個名為 customCount 的屬性上。

請注意,使用 sequelize.literal 時需小心確保代碼的安全性和正確性,以避免潛在的風險和錯誤。請謹慎使用,并確保仔細檢查和測試自定義函數(shù)的邏輯。

模型關(guān)聯(lián)

在 Sequelize 中,模型關(guān)聯(lián)是指在不同表之間建立起的關(guān)系,使得可以通過一個模型對象訪問到與其相關(guān)聯(lián)的其他模型對象的數(shù)據(jù)。

Sequelize 支持多種類型的模型關(guān)聯(lián),包括一對一(One-to-One)、一對多(One-to-Many)和多對多(Many-to-Many)等。通過定義模型之間的關(guān)聯(lián)關(guān)系,我們可以方便地執(zhí)行跨表查詢、創(chuàng)建、更新以及刪除操作,而無需手動編寫復(fù)雜的 JOIN 查詢。

在 Sequelize 中,定義模型關(guān)聯(lián)的方法有以下幾種:

  • hasOne:定義一對一的關(guān)聯(lián)關(guān)系。該方法通常用于聲明一個模型擁有唯一的關(guān)聯(lián)模型。
  • hasMany:定義一對多的關(guān)聯(lián)關(guān)系。該方法通常用于聲明一個模型擁有多個關(guān)聯(lián)模型。
  • belongsToMany:定義多對多的關(guān)聯(lián)關(guān)系。該方法用于建立兩個模型之間的多對多關(guān)聯(lián)關(guān)系,需要通過一個中間模型來實現(xiàn)。
  • belongsTo:定義一對一或一對多的關(guān)聯(lián)關(guān)系。該方法通常用于聲明一個模型屬于另一個模型,也可以用于建立模型之間的一對多關(guān)聯(lián)關(guān)系。

例如,假設(shè)有兩個模型:User(用戶)和Post(帖子)。一個用戶可以擁有多篇帖子,而一篇帖子只能屬于一個用戶。在這種情況下,我們可以通過一對多的關(guān)系來建立模型關(guān)聯(lián)。

可以通過在模型定義中使用 hasMany 和 belongsTo 方法來定義一對多的關(guān)聯(lián)關(guān)系。下面是一個示例:

// User 模型定義
const User = sequelize.define('User', {
  // ...其他屬性
});

// Post 模型定義
const Post = sequelize.define('Post', {
  // ...其他屬性
});

// 建立一對多關(guān)聯(lián)
User.hasMany(Post, { foreignKey: 'userId' });
Post.belongsTo(User, { foreignKey: 'userId' });

在上述示例中,User.hasMany(Post) 表示用戶模型擁有多個帖子,Post.belongsTo(User) 表示帖子模型屬于一個用戶。通過指定外鍵 userId,Sequelize 將根據(jù)該外鍵進行關(guān)聯(lián)查詢。

通過建立模型關(guān)聯(lián),可以使用框架提供的方法來執(zhí)行聯(lián)表查詢,例如:

// 查詢用戶及其所有帖子
const user = await User.findByPk(userId, { include: Post });

// 查詢帖子及其所屬用戶
const posts = await Post.findAll({ include: User });

這樣就可以方便地在相關(guān)聯(lián)的模型之間進行數(shù)據(jù)查詢和操作。

責任編輯:武曉燕 來源: 前端充電寶
相關(guān)推薦

2025-03-03 12:00:00

JavaScriptfor 循環(huán)語言

2022-08-28 10:08:53

前端代碼前端

2023-03-15 15:54:36

Java代碼

2020-07-22 15:15:28

Vue前端代碼

2025-03-10 08:44:17

2024-12-04 08:58:46

2016-05-11 10:09:49

數(shù)據(jù)層代碼FastQuery

2023-09-13 16:34:47

Java工具開發(fā)

2011-07-01 13:42:24

QT 數(shù)據(jù)庫

2009-12-28 16:57:40

ADO .NET 類

2009-09-15 09:50:07

Linq操作數(shù)據(jù)庫

2020-11-16 08:56:02

Python

2011-07-05 10:27:06

MySQL數(shù)據(jù)庫檢索排序

2011-04-19 10:20:09

數(shù)據(jù)庫

2022-07-15 07:58:18

SteampipeCLI 工具

2009-09-03 09:52:26

C# treeview

2021-01-18 18:42:33

工具調(diào)優(yōu)開發(fā)

2015-01-28 14:18:30

androidsqliteintellij

2009-08-24 16:46:04

C# 泛型

2021-01-29 10:51:48

高并發(fā)數(shù)據(jù)庫緩存
點贊
收藏

51CTO技術(shù)棧公眾號