from Mongoosejs & festivalclaca.cat
本篇筆記將解決以下問題:
誰適合閱讀:
前置準備:
在正式動手建立資料庫、設定連線前,透過綜覽本機運行全貌,能對於接下來的行動有所掌握。
承接 全端開發者必懂的「網路觀念」 中提到的運作機制,在實作時所有機器的溝通,包含客戶端與伺服器端、應用程式伺服器與資料庫伺服器的互動,都會在本地環境運行。
而本篇筆記著重談論「MongoDB 的設定與連線」及「如何用 Mongoose 來建立與 DB 互動的 Model」。
在每次開發、測試及運作專案時,資料庫的基礎前置分為三個步驟:
bin
的資料夾,並以 mongod
檔案啟動 MongoDB:[~] $ cd ~/mongodb/bin/
[~/mongodb/bin] $ ./mongod --dbpath ~/mongodb-data
p.s. 記得要把安裝完的資料夾改名為 mongodb
並且新增 mongodb-data
用以存放資料。
參考 Mongoose 官方的 Getting Started 能快速上手資料庫的連線,以下摘錄幾個重要步驟,細節可再閱讀文件。
[~/project_name] $ npm install mongoose --save
// 載入 mongoose
const mongoose = require('mongoose')
// 設定連線到 mongoDB
mongoose.connect('mongodb://localhost/project_name', { useNewUrlParser: true, useUnifiedTopology: true })
mongoose.connect
這段可以理解為,連線至 mongodb://localhost/project_name
這個資料庫。至於後面的參數是 MongoDB 在版本更新的過程中,捨棄某些方法,因而產生的過渡期設定。
透過 mongoose.connection
取得實際連線狀態後,就能針對收到的狀態進行處理:
.on
安裝「連線失敗」的事件監聽器.once
安裝一次性的「連線成功」的事件監聽器// 取得資料庫連線狀態
const db = mongoose.connection
db.on('error', () => { // 連線異常處理
console.log('mongodb error 0.0')
})
db.once('open', () => { // 連線成功處理
console.log('mongodb connected ^_^')
})
當資料庫順利連線,就能來建立資料模型,這會是資料處理的根基與核心。我們會先建立與 Model 有關的資料夾來管理文件,並且為每一種資料建立獨立的資料結構管理文件。
models
來管理所有資料相關的邏輯及處理方式,因為不只一種所以會用複數名詞資料單數名詞
來命名及管理資料結構,以經典全端實務的 Todo List 為例,一個代辦事項就被定義為 todo。在 <Why Define a Mongoose Schema?> 一文中提到:「雖然 MongoDB 是個 schema-less 的資料庫;但由於我們在設計應用程式時,通常某些基礎的資料已經有固定的格式與細節,為了確保能夠保持一致,並且能使用 Mongoose 內建的方法來驗證和處理資料,通常還是會定義基礎的『資料結構 Data Schema』」。
// 引用 mongoose 及其用以定義 Schema 的方法
const mongoose = require('mongoose')
const Schema = mongoose.Schema
// 一筆 Todo 的資料格式
const todoSchema = new Schema({
name: {
type: String, // 資料型別是字串
required: true // 這是個必填欄位
}
})
// 輸出為可供其他檔案應用的 model
module.exports = mongoose.model('Todo', todoSchema)
在 資料庫學習的入門指南 中提及:
NoSQL 的 ODM(Object Document Mapper)以程式語言裡的「物件」來包裝資料庫的 SQL (structured query language),讓開發者可以直接使用物件導向的方式操作資料庫。
所以在操作資料時,多會看到把整個物件當作參數傳進方法中使用。至於物件導向程式設計,之後會在《JavaScript 物件導向——全端開發者內功 I》文章中詳細剖析。
在應用程式初始化的階段,我們通常會設置一些基礎資料,用以預設產品內容、下拉選單選項、管理員帳號等。這些資料統稱為種子資料(seed data)。
種子資料同樣會放在 models 中,由於種子資料可能會有很多種,慣例上也會以複數的 seeds
來存放。
在產生種子資料時,由於會直接操作到資料庫與前面定義好的 Todo model,所以會連同 Mongoose 一起載入。種子資料的生成則會定義在連線成功的 .once
監聽器當中。
// 引用 mongoose 並載入 Todo model
const mongoose = require('mongoose')
const Todo = require('../todo')
// 與資料庫連線
mongoose.connect('mongodb://localhost/todo-list', { useNewUrlParser: true, useUnifiedTopology: true })
// 設定資料連線狀態
const db = mongoose.connection
db.on('error', () => {
console.log('mongodb error 0.0')
})
db.once('open', () => { // 產生種子資料
console.log('mongodb connected ^_^')
for (let i = 0; i < 10; i++) {
Todo.create({ name: 'name-' + i })
}
console.log('done!')
})
並且為了專案協作,通常也會把 seeder 定義在 package.json
腳本中:
"scripts": {
"start": "node app.js",
"dev": "nodemon app.js",
"test": "echo \"Error: no test specified\" && exit 1",
"seed": "node models/seeds/todoSeeder.js" // 新增腳本
},
關於本系列更多內容及導讀,請閱讀作者於 Medium 個人專欄 【無限賽局玩家 Infinite Gamer | Publication – 】 上的文章 《用 JavaScript 打造全端產品的入門學習筆記》系列指南。