使用 Node.js 和 MySQL 創建一個 CRUD 應用程序

介紹

Node.js 是一個用於構建快速且可擴展的網絡應用程序的開源平台。 MySQL 是一個可靠的關係數據庫管理系統 (RDBMS),是使用 Node.js 構建 CRUD(創建、讀取、更新、刪除)應用程序的不錯選擇。

CRUD 應用程序執行以下操作:

  • Create : 使用 SQL 將數據添加到 MySQL 數據庫 INSERT 領域。
  • Read : 使用 SQL 從數據庫中查詢數據 SELECT 領域。
  • Update : 使用 SQL 修改數據記錄 UPDATE 領域。
  • Delete : 使用 SQL 從數據庫中刪除記錄 DELETE 領域。

許多數據驅動的應用程序在 CRUD 編程模式之上運行,包括博客、公司門戶、電子商務軟件、企業資源規劃應用程序等。 本指南在服務器上使用 Node.js 和 MySQL 實現 CRUD 應用程序Ubuntu20.04。

以前的要求

在你開始之前:

  • 部署一個 Ubuntu 服務器。
  • 安裝並保護 MySQL 服務器。
  • 設置 Node.js 編程環境。 您可以跳過第 2 步(安裝 Express.js),因為您不需要 Express.js 依賴項來嘗試本指南。

1.設置數據庫和用戶帳戶

在本指南中,您的示例應用程序將數據永久存儲在 MySQL 數據庫中。 按照以下步驟初始化數據庫並創建用戶帳戶:

  1. 登錄到 MySQL 服務器 root .

                              
                                $ sudo mysql -u root -p
    
                              
                            
  2. 輸入您的密碼,然後按 ENTER 繼續。 然後發出以下 SQL 命令來創建示例 my_shop 數據庫和一個 my_shop_user 賬單。 代替 EXAMPLE_PASSWORD 使用強密碼保護 MySQL 帳戶免受暴力攻擊。

                              
                                mysql> CREATE DATABASE my_shop;
           CREATE USER 'my_shop_user'@'localhost' IDENTIFIED WITH mysql_native_password BY 'EXAMPLE_PASSWORD';
           GRANT ALL PRIVILEGES ON my_shop.* TO 'my_shop_user'@'localhost';           
           FLUSH PRIVILEGES;
    
                              
                            

    生產。

                              
                                ...
    Query OK, 0 rows affected (0.01 sec)
    
                              
                            
  3. 切換到新的 my_shop 數據庫。

                              
                                mysql> USE my_shop;
    
                              
                            

    生產。

                              
                                Database changed
    
                              
                            
  4. 創建一個 products 桌子。 此表存儲的產品信息包括:唯一 product_id , product_name 是的 retail_price . 投 AUTO_INCREMENT 關鍵字允許 MySQL 自動增加 product_id 列中插入新記錄時 products 桌子。

                              
                                mysql> CREATE TABLE products (
               product_id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,
               product_name VARCHAR(50),
               retail_price  DOUBLE
           ) ENGINE = InnoDB;
    
                              
                            

    生產。

                              
                                Query OK, 0 rows affected (0.01 sec)
    
                              
                            
  5. 將示例記錄插入 products 桌子。

                              
                                mysql> INSERT INTO products (product_name, retail_price) values ('LEATHER BELT', 18.45);
           INSERT INTO products (product_name, retail_price) values ('BLUETOOTH SPEAKER', 75.95);
           INSERT INTO products (product_name, retail_price) values ('RECHARGEABLE TORCH', 35.85);
    
                              
                            

    生產。

                              
                                ...
    Query OK, 1 row affected (0.02 sec)
    
                              
                            
  6. 諮詢 products 表以確保數據到位。

                              
                                mysql> SELECT
               product_id ,
               product_name,
               retail_price
           FROM products;
    
                              
                            

    生產。

                              
                                +------------+--------------------+--------------+
    | product_id | product_name       | retail_price |
    +------------+--------------------+--------------+
    |          1 | LEATHER BELT       |        18.45 |
    |          2 | BLUETOOTH SPEAKER  |        75.95 |
    |          3 | RECHARGEABLE TORCH |        35.85 |
    +------------+--------------------+--------------+
    3 rows in set (0.00 sec)
    
                              
                            
  7. 註銷 MySQL 服務器。

                              
                                mysql> QUIT;
    
                              
                            

    生產。

                              
                                Bye
    
                              
                            

2. 創建一個 database_gateway 班級

在處理 Node.js 項目時,慣例是將應用程序分成分佈在不同文件中的可管理模塊。 這種方法允許您快速調試您的應用程序並使支持變得更容易。 此步驟側重於創建一個核心數據庫類,您可以在整個項目中重複使用該類來訪問您的數據庫。

  1. 從創建一個新的開始 project 應用程序目錄。

                              
                                $ mkdir project
    
                              
                            
  2. 切換到新的 project 目錄。

                              
                                $ cd project
    
                              
                            
  3. 開一個新的 database_gateway.js 文本編輯器中的文件。

                              
                                $ nano db_gateway.js
    
                              
                            
  4. 將以下信息添加到 database_gateway.js 訴訟程序。 記得更換 EXAMPLE_PASSWORD 使用正確的 MySQL 密碼 my_shop_user 賬單。

                              
                                class db_gateway { 
    
        constructor() {
    
        }
    
        getDb() { 
    
            const mysql = require('mysql');  
    
            const db_con = mysql.createConnection({
                host: "localhost",
                user: "my_shop_user",
                password: "EXAMPLE_PASSWORD",
                database: "my_shop"
             }); 
    
            db_con.connect(function(err) {
                if (err) {               
                    console.log(err.message);             
                }                    
            });
    
            return db_con;
        } 
    
        execute(sql, params, callBack) {
    
           var db_con = this.getDb();        
    
           db_con.query(sql, params, function (err, result) {
               if (err) {
                   callBack(err, null);                   
               } else {
                   callBack(null, "Success");          
               }         
          }); 
    
        }      
    
        query(sql, params, callBack) {
    
           var db_con = this.getDb();        
    
           db_con.query(sql, params, function (err, result) {
               if (err) {
                   callBack(err, null);                   
               } else {
                   callBack(null, result);          
               }         
          }); 
    
        }      
    }
    
    module.exports = db_gateway;
    
                              
                            
  5. 保存並關閉 db_gateway.js 訴訟程序。

db_gateway.js 文件解釋:

  • 光棍 db_gateway {} 該類包裝了連接到數據庫和執行 CRUD 操作所需的所有數據庫函數。

                              
                                class db_gateway { 
        ....
    }
    
                              
                            
  • constructor() {} 該方法為空,因為您沒有為此類傳遞或初始化任何默認變量。

  • db_gateway {} 該類具有三個主要方法(函數),如下所述:

    • getDb() 此方法連接到 MySQL 數據庫並返回一個可重用的連接 ( return db_con; ) 由實施 execute() 是的 query() 方法。

    • execute() : 這個方法執行 SQL INSERT , UPDATE 是的 DELETE 訂購併返回 Success 中的消息 callBack() 功能。

    • query() : 這個方法執行 SQL SELECT 命令並返回一個關聯數組,其中包含來自 products 桌子。

  • 將數據庫函數映射到一個單獨的類允許您使用以下經典代碼來調用本指南後面的方法:

                              
                                var db_gateway = require('./db_gateway.js');
    var dg = new db_gateway();
    
    dg.execute(sql, params, callBack);  
    dg.query(sql, params, callBack);
    
                              
                            
  • 您可能已經註意到,Node.js 使用了很多回調。 回調是在任務完成時執行的函數。 這種回調模型允許 Node.js 通過防止函數相互阻塞來支持高並發。

  • module.exports = db_gateway; 最後的行允許您利用 db_gateway 在其他文件中使用 require('./db_gateway.js'); 陳述。

db_gateway 課準備好了。 然後,此示例應用程序實現 db_gateway 不同文件中的類以執行數據庫操作。

3. 創建一個 products 班級

CRUD 應用程序中的資源或端點的數量可以從一到幾百不等。 該數字取決於應用程序的複雜性。 例如,以下是典型電子商務應用程序的一些 HTTP 資源和端點:

                      
                        Resource    Endpoint
----------------------

products    /products

categories  /categories

customers   /customers

orders      /orders

payments    /payments

...

                      
                    

在設計應用程序時,您應該為所有資源創建單獨的類,以創建可以輕鬆調試和修復的干淨代碼。 本指南有一個資源/端點( products ) 從 products 桌子。 按照以下步驟為資源創建一個類:

  1. 開一個新的 products.js 文本編輯器中的文件:

                              
                                $ nano products.js
    
                              
                            
  2. 在中輸入以下信息 products.js 訴訟程序。

                              
                                class products {
    
        constructor(dg) {
            this.dg = dg;        
        }
    
        insertRecord(jsonData, callBack) {
    
            var sql = "insert into products (product_name, retail_price) values (?, ?)"; 
    
            var params = [];
    
            params.push(jsonData["product_name"]);  
            params.push(jsonData["retail_price"]); 
    
            this.dg.execute(sql, params, callBack);          
        }
    
        getRecords(resourceId, callBack) {
    
             var sql = "select product_id, product_name, retail_price from products";
    
             var params = []; 
    
             if (resourceId != "") {
                 sql = sql + " where product_id = ?";               
                 params.push(resourceId);    
             }
    
             this.dg.query(sql, params, callBack);
        }
    
        updateRecord(resourceId, jsonData, callBack) {
    
            var sql = "update products set product_name = ?, retail_price = ? where product_id = ?";
    
            var params = [];
    
            params.push(jsonData["product_name"]);  
            params.push(jsonData["retail_price"]); 
            params.push(resourceId); 
    
            this.dg.execute(sql, params, callBack);
        }
    
        deleteRecord(resourceId, callBack) {
    
            var sql = "delete from products where product_id = ?";
    
            var params = [];
    
            params.push(resourceId);   
    
            this.dg.execute(sql, params, callBack);       
        }
    }
    
    module.exports = products;
    
                              
                            
  3. 保存並關閉 products.js 完成編輯後的文件。

products.js 文件解釋:

  • products{} 該類將資源的整個方法包裝在一個文件中。

                              
                                class products {
        ...
    }
    
                              
                            
  • constructor (dg) {..} 方法接受一個 dg 陰謀。 這 dg 指的是他以前的 database_gateway 公開數據庫的不同功能的類。

  • this.dg = dg; 語句初始化一個新的類屬性 ( dg ) 並賦值 database_gateway 對象屬性。

  • products{...} 該類有四個其他方法對應於 CRUD 操作:

    • insertRecord(jsonData, ...) : 接受一個 JSON 有效載荷 (jsonData) 並構建一個 INSERT 陳述。

    • getRecords(resourceId, ...) : 接受一個 resourceId 參數並構建一個 SELECT 陳述。 當你定義 resourceId 在 HTTP 調用期間,MySQL 僅返回與 resourceId 值得。

    • updateRecord(resourceId, jsonData, ...) : 接受一個 resourceId 和一個 JSON 加載並構建一個 UPDATE 命令更改匹配的記錄 resourceId .

    • deleteRecord(resourceId, ...) : 接受一個 resourceId 並建立一個 DELETE 命令刪除匹配的記錄 resourceId .

  • 所有四種 CRUD 方法都通過 callBack 作用於 database_gateway 類使用 this.dg.query(sql, params, callBack); 是的 this.dg.execute(sql, params, callBack); 陳述。 這 callBack() 該函數在操作完成時執行。

  • module.exports = products; 最後的行允許您使用其他文件中的類 require('./products.js'); 陳述。

4. 創建一個 http_requests 班級

此步驟描述了創建一個 http_requests 返回此項目中所需的大多數 HTTP 變量的類。

  1. 開一個新的 http_requests.js 在文本編輯器中。

                              
                                $ nano http_requests.js
    
                              
                            
  2. 在中輸入以下信息 http_requests.js 訴訟程序。

                              
                                class http_requests {
    
        constructor(httpRequest) {
    
            var url = require("url");
    
            this.httpRequest = httpRequest;
    
            var pathname = url.parse(this.httpRequest.url).pathname;
    
            this.resourcePath = pathname.split("https://www.vultr.com/");
            this.resourceId   = "";
            this.httpMethod   = httpRequest.method
    
            if (this.resourcePath.length >= 3) {
                this.resourceId = this.resourcePath[2]
            }   
        }
    
    }  
    
    module.exports = http_requests;
    
                              
                            
  3. 保存並關閉 http_requests.js 訴訟程序。

http_requests.js 文件解釋:

  • http_requests 類將不同的 HTTP 變量包裝在一個 constructor(...) 方法。

                              
                                class http_requests {
    
        constructor(httpRequest) {
    
        }
    }
    
                              
                            
  • constructor(httpRequest){} 方法接受一個 httpRequest 目的。 這個項目來自一個 http 然後您需要導入並包含在不同文件中的庫。

  • pathname.split("https://www.vultr.com/"); 該函數使用 / 字符並返回 resourceId . 例如,如果您請求 URL https://127.0.0.1:8080/products/3 pathname.split("https://www.vultr.com/"); 函數返回 3 作為 resourceId . 邏輯的 if (this.resourcePath.length >= 3) {...} 聲明確保 resourceId 在請求 URL 中可用。

5. 創建一個 main.js 訴訟

您的 Node.js 需要一個在應用程序啟動時執行的主文件。 主文件是應用程序的入口點。 請按照以下步驟創建文件:

  1. 開一個新的 main.js 在文本編輯器中。

                              
                                $ nano main.js
    
                              
                            
  2. 在中輸入以下信息 main.js 訴訟程序。

                              
                                var db_gateway    = require('./db_gateway.js');
    var http_requests = require('./http_requests.js');
    var products      = require('./products.js');   
    
    const http = require('http');
    const hostname="127.0.0.1";
    const port = 8080;
    
    const server = http.createServer((req, res) => { 
    
        var dg = new db_gateway();
        var httpRequest = new http_requests(req);
        var product = new products(dg); 
    
        var payload = "";            
    
        req.on('data', function (data) {
            payload += data;
        });      
    
        req.on('end', function () {
    
            function callBack(err, result) {
    
                res.statusCode = 200;
    
                res.setHeader('Content-Type', 'application/json');
    
                var response = {}
    
                if (err) { 
                    response["error"] = err.message;
                } else {
                    response["data"] = result; 
                }
    
                res.write(JSON.stringify(response, null, 4));
                res.end();
            }
    
            resourceId = httpRequest.resourceId;
    
            switch (req.method) { 
    
                case "POST":
    
                    jsonData =  JSON.parse(payload); 
    
                    product.insertRecord(jsonData, callBack);
    
                    break;
    
                case "PUT": 
    
                    jsonData =  JSON.parse(payload); 
    
                    product.updateRecord(resourceId, jsonData, callBack);
    
                    break;
    
                case "DELETE": 
    
                    product.deleteRecord(resourceId, callBack);
    
                    break; 
    
                case "GET":  
    
                    product.getRecords(resourceId, callBack); 
    
                    break; 
            }
    
        });
    });
    
    server.listen(port, hostname, () => {
        console.log(`Server running at https://${hostname}:${port}/`);
    });
    
                              
                            
  3. 保存並關閉 main.js 訴訟程序。

main.js 文件解釋:

  • 前三行導入您為此項目創建的所有類。

                              
                                var db_gateway    = require('./db_gateway.js');
    var http_requests = require('./http_requests.js');
    var products      = require('./products.js');   
    
                              
                            
  • 以下行導入 http 模塊。 這 http 該模塊運行一個 Web 服務器,用於偵聽端口上的傳入 HTTP 連接 8080 .

                              
                                const http = require('http');
    const hostname="127.0.0.1";
    const port = 8080;
    
                              
                            
  • 以下語句啟動 HTTP 服務器。

                              
                                ...
    
    const server = http.createServer((req, res) => { 
        ...
    });
    
    ...
    
                              
                            
  • 以下行從導入的類創建新對象。

                              
                                ...
    
    var dg = new db_gateway();
    var httpRequest = new http_requests(req);
    var product = new products(dg);
    
    ... 
    
                              
                            
  • 監控 callBack() 該函數在您的應用程序完成 CRUD 操作時執行。 這 callBack() 該函數以 JSON 格式返迴響應。

                              
                                ...
    
    function callBack(err, result) {
    
        res.statusCode = 200;
    
        res.setHeader('Content-Type', 'application/json');
    
        var response = {}
    
        if (err) { 
            response["error"] = err.message;
        } else {
            response["data"] = result; 
        }
    
        res.write(JSON.stringify(response, null, 4));
        res.end();
    }
    
    ...
    
                              
                            
  • switch() {} 語句檢查 HTTP 方法 ( req.method ) 並將方法與正確的方法相匹配。 product's 根據以下列表完成 HTTP 操作的方法:

    • POST : 執行 product.insertRecord(jsonData, callBack); 陳述。

    • PUT : 執行 product.updateRecord(resourceId, jsonData, callBack); 陳述。

    • DELETE : 執行 product.deleteRecord(resourceId, callBack); 陳述。

    • GET : 執行 product.getRecords(resourceId, callBack); 陳述。

6. 測試 Node.Js CRUD 應用程序

該應用程序現在已準備好進行測試。 您的數據庫和源代碼文件已就位。 運行以下步驟來初始化您的 Node.js 項目目錄,下載必要的模塊,並使用 Linux 運行測試 curl 領域:

  1. 初始化您的項目目錄。

                              
                                $ npm init
    
                              
                            

    輸入以下答案:

                              
                                package name: (project) : Press ENTER to leave as default.
    
    version: (1.0.0) : Press ENTER to leave as default.
    
    description: Press ENTER to leave as default.
    
    entry point: (main.js) Press ENTER to leave as default.
    
    test command: Press ENTER to leave as default.
    
    git repository: Press ENTER to leave as default.
    
    keywords: Press ENTER to leave as default.
    
    author: Press ENTER to leave as default.
    
                              
                            

    許可證:(ISC)按 ENTER 保留默認值。

    Node.js npm 包返回以下響應。

                              
                                About to write to /home/francis/project/package.json:
    
    {
      "name": "project",
      "version": "1.0.0",
      "description": "",
      "main": "main.js",
      "scripts": {
        "test": "echo "Error: no test specified" && exit 1"
      },
      "author": "",
      "license": "ISC"
    }
    
    Is this OK? (yes)
    
                              
                            

    鑰匙是的並按 ENTER 確認更改。

  2. 使用 Node.js 包管理器( npm ) 下載並導入 mysql 項目中的庫。

                              
                                $ npm install mysql
    
                              
                            

    生產。

                              
                                npm notice created a lockfile as package-lock.json. You should commit this file.
    npm WARN [email protected] No description
    npm WARN [email protected] No repository field.
    
    + [email protected]
    added 11 packages from 15 contributors and audited 11 packages in 1.079s
    found 0 vulnerabilities
    
                              
                            
  3. 跑過 main.js 文件使用 node 領域。 以下命令設置一個 HTTP 服務器,用於偵聽端口上的傳入連接 8080 . 這 node main.js 該命令具有阻塞功能。 因此,不要在活動終端窗口中運行任何其他命令。

                              
                                $ node main.js
    
                              
                            

    生產。

                              
                                Server running at https://127.0.0.1:8080/
    
                              
                            
  4. 在第二個終端窗口中建立與服務器的新 SSH 連接並使用 curl 執行以下 CRUD 操作:

    • Create operation : 添加一條新記錄到 products 桌子。

                                    
                                      $ curl -X POST https://127.0.0.1:8080/ -H 'Content-Type: application/json' -d '{"product_name":"DOUBLE-SIDED TAPE","retail_price": 4.95}'
      
                                    
                                  

      生產。

                                    
                                      {
          "data": "Success"
      }
      
                                    
                                  
    • Read operation - all records : 從 products 桌子。

                                    
                                      $ curl -X GET https://127.0.0.1:8080/products 
      
                                    
                                  

      生產。

                                    
                                      {
          "data": [
              {
                  "product_id": 1,
                  "product_name": "LEATHER BELT",
                  "retail_price": 18.45
              },
              {
                  "product_id": 2,
                  "product_name": "BLUETOOTH SPEAKER",
                  "retail_price": 75.95
              },
              {
                  "product_id": 3,
                  "product_name": "RECHARGEABLE TORCH",
                  "retail_price": 35.85
              },
              {
                  "product_id": 4,
                  "product_name": "DOUBLE-SIDED TAPE",
                  "retail_price": 4.95
              }
          ]
      }
      
                                    
                                  
    • Read operation - one record : 從 products 匹配的表 resourceId 在 URL 的末尾(例如, 4 )。

                                    
                                      $ curl -X GET https://127.0.0.1:8080/products/4
      
                                    
                                  

      生產。

                                    
                                      {
          "data": [
              {
                  "product_id": 4,
                  "product_name": "DOUBLE-SIDED TAPE",
                  "retail_price": 4.95
              }
          ]
      }
      
                                    
                                  
    • Update operation :修改匹配的產品的詳細信息 resourceId (例如, 3 )。

                                    
                                      $ curl -X PUT https://127.0.0.1:8080/products/3 -H 'Content-Type: application/json' -d '{"product_name":"RECHARGEABLE LED TORCH","retail_price": 40.20}'
      
                                    
                                  

      生產。

                                    
                                      {
          "data": "Success"
      }
      
                                    
                                  

      請求產品 ( product_id 3 ) 檢查更新命令是否成功。

                                    
                                         $ curl -X GET https://127.0.0.1:8080/products/3
      
                                    
                                  

      生產。

                                    
                                      {
          "data": [
              {
                  "product_id": 3,
                  "product_name": "RECHARGEABLE LED TORCH",
                  "retail_price": 40.2
              }
          ]
      }
      
                                    
                                  
    • Delete Operation :刪除匹配的產品 resourceId (例如, 4 )。

                                    
                                      $ curl -X DELETE https://127.0.0.1:8080/products/4
      
                                    
                                  

      生產。

                                    
                                          {
              "data": "Success"
          } 
      
                                    
                                  

      再次檢查產品以驗證刪除操作是否成功。

                                    
                                          $ curl -X GET https://127.0.0.1:8080/products/4
      
                                    
                                  

      生產。

                                    
                                          {
              "data": []
          }
      
                                    
                                  

以上結果表明您的 Node.js CRUD 應用程序按預期工作。

結論

本指南是在 Ubuntu 20.04 上使用 Node.js 和 MySQL 數據庫服務器實現 CRUD 應用程序的完整演練。 使用本指南中的知識來編寫您的下一個 Node.js 項目。 您可以根據項目的複雜性在 Node.js 應用程序中添加盡可能多的端點/資源。 請記住將每個資源分成不同的類文件,以方便將來的支持。

文章標題 名稱(可選) 電子郵件(可選) 描述

發送建議

相關文章