如何使用Sequelize实现查询指定用户点赞歌曲的SQL语句?
Sequelize 实现目标SQL的代码写法
对应需求的原SQL逻辑为:查询所有被 userId=1 的用户点赞过的歌曲全量记录,共两种常用可落地的实现方案:
方案一:拆分子查询逻辑,使用Op.in匹配
这种写法是Sequelize中最常用的关联查询拆分方式,逻辑清晰易维护:
- 前置依赖:提前引入Sequelize的操作符
Op、已定义完成的Song(对应Songs表)、Like(对应Likes表)模型实例
const { Op } = require('sequelize'); const { Song, Like } = require('./模型引入路径'); const likedSongs = await Song.findAll({ where: { Id: { [Op.in]: async () => { // 查出目标用户点赞记录里的所有songId const likeList = await Like.findAll({ attributes: ['songId'], where: { userId: 1 }, raw: true }); // 提取为纯数值数组传入IN条件 return likeList.map(item => item.songId); } } } });
方案二:嵌入原生子查询,完全匹配目标SQL
这种写法生成的执行SQL和你提供的原生语句完全一致,不会因为Sequelize的自动转义规则出现逻辑偏差,适合对查询逻辑有精准校验要求的场景:
const { Op, sequelize } = require('sequelize'); const { Song } = require('./模型引入路径'); const likedSongs = await Song.findAll({ where: sequelize.where( sequelize.col('Id'), Op.in, sequelize.literal(`( SELECT "songId" FROM "Likes" WHERE "userId" = 1 )`) ), raw: true });
注意事项
- 上述代码仅适配Sequelize 6.x及以上版本,低版本Sequelize需要手动执行两次查询、拼接结果数组的方式实现
- 加上
raw: true配置后,查询结果会直接返回纯JSON格式的字段值,不需要额外遍历剥离Sequelize模型实例的冗余属性,查询性能更优 - 如果查询涉及的表名、字段名和你定义的模型映射规则不一致,可以在方案二的字面量里直接修改对应表名字段,不需要调整模型配置
内容的提问来源于stack exchange,提问作者Simon Moulin
相关产品推荐
相关产品推荐

