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

如何在Express中执行多条MySQL插入操作后统一返回响应

Express+MySQL 批量插入完成后再返回响应的实现方案

首先你现有代码无法满足需求的核心原因和存在的问题:

  • 数据库query操作为异步回调执行,循环内的子表插入操作还未全部执行完成,外层就已经调用res.status(200).send()返回了响应
  • 直接拼接用户传入的参数到SQL语句中,存在严重的SQL注入风险
  • 存在多处笔误:循环中取子项参数应为req.body.items[i].name而非req.items.name,数据库连接对象connection和con混用
  • 没有事务保障,可能出现主表插入成功、子表部分插入成功的脏数据问题

推荐实现方案(带事务保障 + async/await)

该方案使用mysql2的promise API,配合事务实现要么全成功要么全回滚的原子性操作,逻辑清晰易维护:

  1. 首先安装mysql2依赖:
    npm install mysql2
  2. 配置数据库连接池(性能优于单连接):
const mysql = require('mysql2/promise');
const pool = mysql.createPool({
  host: '你的数据库地址',
  user: '数据库用户名',
  password: '数据库密码',
  database: '数据库名称',
  connectionLimit: 10
});
  1. 接口实现代码:
app.post("/api/eeee", async (req, res) => {
  let connection;
  try {
    // 获取连接并开启事务
    connection = await pool.getConnection();
    await connection.beginTransaction();

    // 插入主表数据,使用预编译语句避免SQL注入
    const [docResult] = await connection.execute(
      'INSERT INTO documents (name) VALUES (?)',
      [req.body.name]
    );
    const docId = docResult.insertId;

    // 组装子表批量插入参数,一次性执行批量插入(性能远高于循环单条插入)
    const insertParams = req.body.items.map(item => [docId, item.name]);
    await connection.query(
      'INSERT INTO doc_items (document, name) VALUES ?',
      [insertParams]
    );

    // 所有操作成功提交事务
    await connection.commit();
    res.status(200).json({ code: 200, msg: '插入成功' });
  } catch (err) {
    // 任何步骤出错回滚事务,保证数据一致性
    if (connection) await connection.rollback();
    res.status(500).json({ code: 500, msg: '插入失败', error: err.message });
  } finally {
    // 释放数据库连接
    if (connection) connection.release();
  }
});

回调版本兼容实现(无需修改原有mysql依赖)

如果你不想更换现有mysql依赖的回调写法,可以用计数法判断所有插入是否完成:

app.post("/api/eeee", (req, res) => {
  // 预编译传参避免SQL注入
  const insertDocSql = "INSERT INTO documents (name) VALUES (?)";
  connection.query(insertDocSql, [req.body.name], (error, result) => {
    if (error) {
      return res.status(500).json({ msg: '主文档插入失败' });
    }
    const docId = result.insertId;
    const items = req.body.items;
    const totalCount = items.length;
    let finishCount = 0;
    let hasError = false;

    for (let i = 0; i < totalCount; i++) {
      const insertItemSql = "INSERT INTO doc_items (document, name) VALUES (?,?)";
      connection.query(insertItemSql, [docId, items[i].name], (err) => {
        if (err) {
          hasError = true;
          return res.status(500).json({ msg: '子项插入失败' });
        }
        finishCount++;
        // 所有子项插入完成后再返回响应
        if (finishCount === totalCount && !hasError) {
          res.status(200).json({ msg: '插入成功' });
        }
      });
    }
  });
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 08:30:04