nodejs 連線 mysql 查詢事務處理

阿政想暴富發表於2021-11-01

自己用 mysql 很多次的,然後又是主玩nodejs的.專門寫一篇文章來說說nodejs連線mysql資料庫。在使用之前,請檢查計算機是否具有一下環境!

  • nodejs 執行環境。
  • mysql資料庫環境(下載地址)。
  • navicat 連線 mysql 資料庫的圖形化操作軟體。(非必要)

檢查環境

進入正題 mysql 增刪改查

首先,我們去下載一個叫mysql的依賴包,這個包就是通過 nodejs 程式碼去連線資料庫,從而運算元據庫。

  • 建立一個資料夾,快速生成pakeage.json檔案
D:\nodejs_mysql>npm init -y  # 快速傳建立包管理檔案
  • 安裝依賴
D:\nodejs_mysql>npm i mysql -D # 安裝mysql 依賴包
  • 建立一個 index.js 檔案,程式碼如下
const mysql = require("mysql");

// 建立 一個mysql 連線池
const pool = mysql.createPool({
  host: "127.0.0.1", // 連線資料庫的地址 127.0.0.1 為本地的mysql
  user: "root", //  連線資料庫的使用者名稱 root 是最高許可權
  password: "", //  連線資料庫的密碼
  database: "apm", // 操作的資料庫名
  port: "3306", // 連線mysql的埠號
  multipleStatements: true, // 執行一次執行多條sql語句 可以忽略此項
});

function select() {
  // 請求連線mysql
  pool.getConnection((err, connection) => {
    // 未連線成功 報錯
    if (err) throw err;
    // 得到一個 連線物件 呼叫 query 方法 可以執行 sql 語句
    let sql = "select * from goods";
    // 執行sql語句 query 第二個引數為 sql語句需要的引數 ,沒有可以不寫
    connection.query(sql, (errors, results, fields) => {
      // 釋放連線
      connection.release();
      // 如果執行sql語句有報錯 丟擲錯誤
      if (errors) throw errors;
      console.log(results);
      console.log(fields);
    });
  });
}

select();

以上的程式碼是查詢 資料庫apm一個資料表goods的資料。results為從資料庫取出的資料。

  • 封裝方法 使用Promise來查詢資料庫
//  index.js
// ... 忽略前面的建立mysql連線池程式碼
function query(sql, params) {
  return new Promise((resolve, reject) => {
    pool.getConnection((err, connection) => {
      // 未連線成功 報錯
      if (err) return reject(err);
      // 得到一個 連線物件 呼叫 query 方法 可以執行 sql 語句
      // 執行sql語句 query 第二個引數為 sql語句需要的引數 ,沒有可以不寫
      connection.query(sql, params, (errors, results, fields) => {
        // 釋放連線
        connection.release();
        // 如果執行sql語句有報錯 丟擲錯誤
        if (errors) return reject(errors);
        resolve(results);
      });
    });
  });
}

query("select * from goods", null).then((result) => {
  console.log(result);
});
module.exports = {
  query,
};
  • 使用
// data.js
const index = require("./index.js");
var sql = "select * from goods";
index
  .query(sql, null)
  .then((result) => {
    // do anything ....
  })
  .catch((err) => {
    // error
    console.log(err);
  });

這樣就向外暴露了一個資料庫執行 sql 的介面。通過promise使用.then這種鏈式呼叫的程式碼風格。

mysql 事務處理

說到 mysql 事務,我也就不做過多介紹了,這裡給個友情連結方便大家學習。MySQL 事務處理

我們直接步入正題,使用promise來封裝 mysql 的事務處理.

// index.js

// .... 部分建立 pool 的程式碼

/**
 * mysql 事務處理
 * @param {Array} sqls 需要執行的sql語句
 * @param {Array} params 對應上面sql語句的引數
 * @returns {Promise} 返回一個Promise
 */
function transaction(sqls, params) {
  return new Promise((resolve, reject) => {
    pool.getConnection(function (err, connection) {
      // 連線失敗 promise直接返回失敗
      if (err) {
        return reject(err);
      }
      // 如果 語句和引數數量不匹配 promise直接返回失敗
      if (sqls.length !== params.length) {
        connection.release(); // 釋放掉
        return reject(new Error("語句與傳值不匹配"));
      }
      // 開始執行事務
      connection.beginTransaction((beginErr) => {
        // 建立事務失敗
        if (beginErr) {
          connection.release();
          return reject(beginErr);
        }
        console.log("開始執行事務,共執行" + sqls.length + "條語句");
        // 返回一個promise 陣列
        let funcAry = sqls.map((sql, index) => {
          return new Promise((sqlResolve, sqlReject) => {
            const data = params[index];
            connection.query(sql, data, (sqlErr, result) => {
              if (sqlErr) {
                return sqlResolve(sqlErr);
              }
              sqlReject(result);
            });
          });
        });
        // 使用all 方法 對裡面的每個promise執行的狀態 檢查
        Promise.all(funcAry)
          .then((arrResult) => {
            // 若每個sql語句都執行成功了 才會走到這裡 在這裡需要提交事務,前面的sql執行才會生效
            // 提交事務
            connection.commit(function (commitErr, info) {
              if (commitErr) {
                // 提交事務失敗了
                console.log("提交事務失敗:" + commitErr);
                // 事務回滾,之前執行的sql語句不生效
                connection.rollback(function (err) {
                  if (err) console.log("回滾失敗:" + err);
                  connection.release();
                });
                // 返回promise失敗狀態
                return reject(commitErr);
              }

              connection.release();
              // 事務成功 返回 每個sql執行的結果 是個陣列結構
              resolve(arrResult);
            });
          })
          .catch((error) => {
            // 多條sql語句執行中 其中有一條報錯 直接回滾
            connection.rollback(function () {
              console.log("sql執行失敗: " + error);
              connection.release();
              reject(error);
            });
          });
      });
    });
  });
}
module.exports = {
  transaction,
};
  • 之後只需要呼叫這個方法就可以執行 mysql 事務了
// data.js
const index = require("./index.js");
var sqls = [
  "delete from goods where goods_id = ?", // 刪除 語句
  "update goods set num = ? where goods_id = ?;", // 更新語句
];
var params = [
  [1], // parmas 是陣列格式 與sqls裡的sql語句裡 ? 一一對應
  [5, 3],
];

index
  .transaction(sqls, params)
  .then((arrResult) => {
    // do anything ....
  })
  .catch((err) => {
    // error
    console.log(err);
  });

以上就是對nodejs操作mysql資料庫的方法,經驗總結。

相關文章