You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为MySQL查询结果对象添加isLiked字段并返回给客户端?

问题原因及解决方案

核心问题分析

  1. 异步时序错误:connectDB.query是异步操作,你在循环中发起的点赞状态查询还未执行完成,就提前调用了res.json(post_result),此时isLiked字段还未被赋值到结果对象中。
  2. 字段名大小写不一致:代码中同时出现了isliked(小写d)和isLiked(大写L),导致字段名混乱。
  3. SQL注入风险:直接通过字符串拼接生成SQL语句(如${req.user['uid']}),存在严重的安全漏洞。

方案一:单条SQL查询直接获取结果(推荐,性能最优)

通过LEFT JOIN关联post_likes表,用CASE语句一次性判断当前用户的点赞状态,避免多次异步查询的时序问题,同时减少数据库请求次数。

const fetchPost = (req, res, next) => {
  // 使用参数化查询避免SQL注入,?为占位符
  const sql = `
    SELECT 
      account.name, account.username, post.content, post.likes, 
      post.visibility, post.date, post.time, post.profile, post.id,
      CASE WHEN pl.post_id IS NOT NULL THEN TRUE ELSE FALSE END AS isLiked
    FROM post 
    INNER JOIN account ON account.uid = post.user_id 
    LEFT JOIN post_likes pl ON pl.post_id = post.id AND pl.user_id = (SELECT id FROM account WHERE uid = ?)
    WHERE post.visibility IN ('Friends', 'Public')
  `;

  connectDB.query(sql, [req.user['uid']], (err, post_result) => {
    if (err) {
      console.log(err);
      return next(createCustomError(err, 400));
    }
    res.status(200).json(post_result);
  });
};

方案二:用Promise + async/await处理异步循环

如果需要保留分步查询的逻辑,可将数据库查询转为Promise,配合async/await和Promise.all确保所有点赞状态查询完成后再返回响应。

const fetchPost = async (req, res, next) => {
  try {
    // 1. 查询公开/好友可见的帖子
    const postSql = `
      SELECT account.name,account.username,post.content,post.likes, post.visibility,post.date,post.time, post.profile, post.id 
      FROM post 
      INNER JOIN account ON account.uid = post.user_id 
      WHERE post.visibility = 'Friends' OR post.visibility = 'Public'
    `;
    const [post_result] = await connectDB.promise().query(postSql);

    // 2. 查询当前用户ID(参数化查询)
    const getUidSql = `SELECT id FROM account where uid = ?`;
    const [user_id_result] = await connectDB.promise().query(getUidSql, [req.user['uid']]);
    const userId = user_id_result[0]['id'];

    // 3. 批量查询所有帖子的点赞状态
    await Promise.all(post_result.map(async (post) => {
      const likeSql = `SELECT user_id, post_id FROM post_likes WHERE post_id = ? AND user_id = ?`;
      const [likeResult] = await connectDB.promise().query(likeSql, [post.id, userId]);
      post.isLiked = likeResult.length > 0;
    }));

    // 4. 所有查询完成后返回响应
    res.status(200).json(post_result);
  } catch (err) {
    console.log(err);
    return next(createCustomError(err, 400));
  }
};

关键改进点

  • 两种方案均使用参数化查询,彻底规避SQL注入风险。
  • 统一字段名为isLiked,避免大小写混乱。
  • 方案一通过单次数据库请求完成所有逻辑,性能远优于多次查询。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 09:43:21