iT邦幫忙

2026 iThome 鐵人賽

DAY 13
0

Day 13:資料庫降臨!MongoDB 與 Mongoose 的架構與連線實戰

系列: 不要再說你不會後端!30 天 Node.js 降維打擊指南
前情提要: 在前面的章節中,我們學會了 RESTful API 設計、Middleware 機制與 Request 資料驗證。但目前所有的資料都是存在記憶體中,伺服器一重啟資料就消失了。今天我們要正式引入持久化儲存的利器——MongoDB 與 Mongoose!


1. 為什麼選擇 MongoDB (NoSQL)?

對於 Node.js 開發者來說,MongoDB 是最親切且主流的資料庫選擇:

  • JSON-like 文件結構(BSON):資料儲存格式與 JavaScript 物件幾乎一模一樣,不需要進行複雜的關聯轉譯。
  • 無 Schema 彈性(Schema-less):欄位擴充方便,非常適合快速疊代與開發。
  • 高效能與高擴展性:針對讀寫頻繁的 Web 應用有極佳的處理能力。

MongoDB 核心名詞對照

關聯式資料庫 (RDBMS / SQL) MongoDB (NoSQL) 說明
Database Database 資料庫
Table Collection 資料集合(如 users)
Row / Record Document 單筆 JSON 文件資料
Column Field 資料欄位(鍵值對)

2. 什麼是 Mongoose?

雖然 MongoDB 本身彈性很大,但在實際團隊開發中,如果完全沒有資料規範,資料庫很快就會變成無序的垃圾場。

Mongoose 是 Node.js 最熱門的 ODM (Object Document Mapper) 工具,它幫我們提供了:

  1. Schema 規範:強制定義 Document 的欄位結構與型態。
  2. Model 抽象化:提供方便的 JavaScript API(如 find(), create(), findById())來操作資料庫。
  3. 內建驗證與 Hook 機制:能在資料寫入前自動檢查或執行指定邏輯。

3. 安裝與建立 Mongoose 連線

安裝 Mongoose

npm install mongoose

建立連線模組 config/db.js

const mongoose = require('mongoose');

const connectDB = async () => {
  try {
    // 預設本機 MongoDB 連線字串 (可替換為 MongoDB Atlas 雲端網址)
    const conn = await mongoose.connect('mongodb://localhost:27017/my_app');

    console.log(`MongoDB 連線成功: ${conn.connection.host}`);
  } catch (error) {
    console.error(`MongoDB 連線失敗: ${error.message}`);
    // 連線失敗時終步程序
    process.exit(1);
  }
};

module.exports = connectDB;


4. 定義第一個 Schema 與 Model

在 Mongoose 中,標準流程是:先定義 Schema(資料規格)➔ 再建立 Model(操作介面)。

建立 models/User.js

const mongoose = require('mongoose');

// 1. 定義 Schema
const userSchema = new mongoose.Schema(
  {
    username: {
      type: String,
      required: [true, '使用者名稱為必填欄位'],
      trim: true,
      minlength: [3, '名稱最少需要 3 個字元']
    },
    email: {
      type: String,
      required: [true, 'Email 為必填欄位'],
      unique: true, // 確保 Email 不會重複
      lowercase: true
    },
    age: {
      type: Number,
      default: 18
    },
    role: {
      type: String,
      enum: ['user', 'admin'],
      default: 'user'
    }
  },
  {
    timestamps: true // 自動新增 createdAt 與 updatedAt 欄位
  }
);

// 2. 建立並匯出 Model (Mongoose 會自動將 User 轉為小寫複數的集合名稱 'users')
const User = mongoose.model('User', userSchema);

module.exports = User;


5. 整合至 Express 主程式

最後,我們在 app.js 中啟動資料庫連線並測試寫入資料:

const express = require('express');
const connectDB = require('./config/db');
const User = require('./models/User');

const app = express();
app.use(express.json());

// 啟動資料庫連線
connectDB();

// 測試新增使用者的 API
app.post('/api/users', async (req, res) => {
  try {
    const newUser = await User.create(req.body);
    res.status(201).json({
      success: true,
      data: newUser
    });
  } catch (error) {
    res.status(400).json({
      success: false,
      message: error.message
    });
  }
});

app.listen(3000, () => {
  console.log('Server is running on http://localhost:3000');
});


6. 今日重點整理

[!IMPORTANT]

  1. Schema 定義結構,Model 負責操作:Schema 是藍圖,Model 是實際拿來呼叫資料庫 API 的元件。
  2. unique: true 不是驗證器:它是 MongoDB 建立索引的方式,要避免重複寫入建議搭配應用層的驗證。
  3. **善用 timestamps: true**:可以在 Schema 設定中開啟自動維護建立與更新時間欄位。


上一篇
Day 12:請求資料的守門員--Express 中得 Request Data與驗證機制
下一篇
Day 14:第二階段總結與實作(任務管理 RESTful API)
系列文
不要再說你不會後端!30 天 Node.js 降維打擊指南 共 16 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
愛瘸瘸
iT邦新手 5 級 ‧ 2026-09-27 23:12:01

學長好刺激

我要留言

立即登入留言