You need to enable JavaScript to run this app. Sequelize中raw:true与raw:false有什么区别?附实际使用示例
优惠活动
大模型
产品
解决方案
定价
更多

Sequelize中raw:true与raw:false有什么区别?附实际使用示例

核心概念说明
  • field setter:是你在模型定义中给真实存储在数据库的字段配置的setter方法,用于字段赋值/写入数据库时自动处理值,比如给password字段配置setter实现自动加密。
  • virtual setter:是给虚拟字段(仅存在于Sequelize实例层、不会实际写入数据库的字段)配置的setter方法,比如可以定义fullName虚拟字段,赋值时自动拆分存入firstName、lastName两个真实字段。
options.raw 参数的差异说明

raw参数的核心作用是控制Sequelize是否返回原生数据库查询结果:

  • 当raw: true时,直接返回数据库返回的原生JSON数据,不会把结果包装成Sequelize模型实例,所有和实例相关的setter、getter、虚拟字段逻辑都会失效,返回的就是纯数据对象。
  • 当raw: false(默认值)时,查询结果会被包装为对应模型的实例,会自动触发所有配置的getter、setter逻辑,也可以正常访问虚拟字段。

效果对比示例

我们给你的users模型扩展setter和虚拟字段配置:

const bcrypt = require('bcryptjs')
let users = db.define('users', {
    id: {
      type: DataTypes.UUID,
      defaultValue: DataTypes.UUIDV4,
      allowNull: false,
      primaryKey: true
    },
    email: {
        type: DataTypes.STRING,
        allowNull: false,
        unique: 'email'
    },
    password: {
      type: DataTypes.STRING,
      // 真实字段的setter:写入时自动加密密码
      set(val) {
        this.setDataValue('password', bcrypt.hashSync(val, 10))
      }
    },
    firstName: DataTypes.STRING,
    lastName: DataTypes.STRING,
    fullName: {
      // 虚拟字段,不会存入数据库
      type: DataTypes.VIRTUAL,
      get() {
        return `${this.getDataValue('firstName')} ${this.getDataValue('lastName')}`
      }
    }
  }
)

查询时的返回差异:

// 情况1:raw = true
const userRaw = await users.findOne({ where: {email: 'test@example.com'}, raw: true })
console.log(userRaw) 
// 输出仅包含数据库实际存储的字段:id、email、password、firstName、lastName,没有fullName字段

// 情况2:raw = false
const userInstance = await users.findOne({ where: {email: 'test@example.com'} })
console.log(userInstance.toJSON())
// 输出包含fullName虚拟字段,所有配置了getter的字段都会按逻辑返回对应值
beforeCount钩子中修改options.raw的差异

count查询本身的返回结果是统计数值,raw参数影响的是count查询的内部逻辑:

  • options.raw: true是Sequelize默认配置,count查询会直接执行原生SQL统计行数,性能更高,绝大多数无关联查询的场景下统计结果都是准确的。
  • options.raw: false时,count查询会先把中间查询结果包装为模型实例,再做去重统计,性能更低,仅在带关联的复杂查询场景下需要使用。

效果对比示例

如果你的count查询关联了一对多的子表,比如统计有已支付订单的用户数量:

// 统计有已支付订单的用户数
const count = await users.count({
  include: [{ model: orders, where: { status: 'paid' } }]
})
  • raw: true时:返回原生SQL统计的行数,一个用户如果有多个已支付订单,会被统计多次,最终count值会大于实际符合条件的用户数量。
  • raw: false时:Sequelize会先把结果包装为用户实例自动去重,返回的是真实符合条件的用户数量,但查询耗时会更高。

内容的提问来源于stack exchange,提问作者CCCC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.20 17:54:02