Sequelize查询Product模型时如何动态调整字段值且不修改存储数据
实现方案
有两种成熟方案可满足需求,均不会修改数据库中存储的原始price数据:
方案1:使用字段Getter方法(推荐)
Getter 是 Sequelize 提供的字段读取钩子,每次访问price字段时会自动执行计算逻辑,适配所有查询场景和单个实例字段读取场景。
修改后的Product模型代码如下:
const { Model, } = require("sequelize"); module.exports = (sequelize, DataTypes) => { class Product extends Model { static associate(models) { // 注意原代码这里的Plan是笔误,应该改为Product Product.belongsTo(models.Supplier); Product.hasMany(models.Order, { foreignKey: "productId", }); } } Product.init({ price: { type: DataTypes.INTEGER, get() { // 先读取数据库存储的原始值 const rawPrice = this.getDataValue('price'); // 计算上浮30%后的值,可根据业务需求调整精度处理逻辑 return rawPrice ? Math.round(rawPrice * 1.3) : rawPrice; } }, }, { sequelize, modelName: "Product", }); return Product; };
如果需要获取原始price值,可调用实例的getDataValue('price')方法。
方案2:使用afterFind查询钩子
如果仅需要在调用findOne/findAll查询时返回上浮后的值,后续操作实例时仍可直接读取原始值,可选用查询钩子方案:
const { Model, } = require("sequelize"); module.exports = (sequelize, DataTypes) => { class Product extends Model { static associate(models) { Product.belongsTo(models.Supplier); Product.hasMany(models.Order, { foreignKey: "productId", }); } } Product.init({ price: DataTypes.INTEGER, }, { sequelize, modelName: "Product", hooks: { afterFind(result) { // 同时兼容findAll返回的数组和findOne返回的单个实例 const list = Array.isArray(result) ? result : [result]; list.forEach(item => { if (item?.price) { item.price = Math.round(item.price * 1.3); } }) } } }); return Product; };
内容的提问来源于stack exchange,提问作者masatoshi000
相关产品推荐
相关产品推荐

