Mongoose的使用,以及表單增刪改查實戰


Mongoose的使用

4.1簡介

Mongoose是一個對象文檔模型(ODM)庫,它對Node原生的MongoDB模塊進行了進一步的優化封裝,並提供了更多的功能。

4.2優勢

1)       可以為文檔創建一個模式結構(Schema)

2)       可以對模型中的對象/文檔進行驗證

3)       數據可以通過類型轉換轉換為對象模型

4)       可以使用中間件來應用業務邏輯掛鈎

5)       比Node原生的MongoDB驅動更容易

4.3核心對象

4.3.1 Schema

模式(約束)對象,通過Schema可以對集合進行約束

4.3.2 Model

模型對象,相當於數據庫中的集合,通過該對象可以對集合進行操作

4.3.3 Document

文檔對象,它和數據庫中的文檔相對應,通過它可以讀取文檔的信息,也可以對文檔進行各種操作

4.4使用

4.4.1連接數據庫

npm init  先自動創建一個package.json文件

1)       下載安裝Mongoose

npm i mongoose --save

2)       引入Mongoose

var mongoose = require("mongoose");

3)       連接MongoDB數據庫

mongoose.connect("mongodb://ip地址:端口號/數據庫名");

 

const  mongoose = require("mongoose");


//1.連接數據庫
// connect 
//第一個實參是數據庫地址URL
//第二個實參是配置對象
//第三個實參是連接數據庫的回調參數
 mongoose.connect("mongodb://localhost:27017/0318_mongoose_demo",{
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex:true
},function(err){
    if(err){
        console.log("連接數據庫失敗");
    }else{
        console.log("連接數據庫成功");
    }
});


// mongoose.connection.once("open",function(err){
//     if(err){
//         console.log("連接數據庫失敗");
//     }else{
//         console.log("連接數據庫成功");
//     }
// })

// 2.創建約束對象(Schema)
let starsSchema = new mongoose.Schema({
    name:{
        type:String,    //聲明當前字段數據類型
        required:true,  //聲明當前字段是否必傳
        unique:true     //聲明當前字段是否唯一
    },
    age:Number,
    sex:{
        type:String,
        default:"未知" //聲明當前字段的默認值
    },
    roles:[String],    //聲明當前字段數據類型為數組, 內部子元素的類型必須是String
    info:mongoose.Schema.Types.Mixed
})

//3.創建模型對象(Model)
//第一個實參->集合名稱
//第二個實參->約束對象
let starsModel = mongoose.model('stars',starsSchema);

//4.創建文檔對象
let starDocument = new starsModel({
    name:"彭於晏",
    age:18.01,
    sex:"猛男",
    roles:["唐鈺小寶"],
    info:"斷臂帥哥"
})

//5.將文檔對象存儲至數據庫中,是一個promise對象
starDocument.save()
    .then(function(){
        console.log('數據添加成功!!!')
    })

即可將數據保存在mongodb中,前提是mongodb服務已啟動

 

使用方式

1)       Model的方法

                  create()

                           - 創建一個或多個文檔對象並添加到數據庫中

                  find()

                           - 查找所有符合條件的文檔,返回的是數組

                  update()

                           - 修改(替換)一個或多個

                  remove()

                           - 刪除一個或多個文檔

 

let mongoose = require('mongoose');

//1.連接數據庫
mongoose.connect("mongodb://localhost:27017/0318_mongoose_demo",{
    useNewUrlParser: true,
    useUnifiedTopology: true,
    useCreateIndex:true
},function(err){
    if(err){
        console.log("連接失敗")
    }else{
        console.log("連接成功")
    }
})

// 2.創建約束對象(Schema)
let starsSchema = new mongoose.Schema({
    name:{
        type:String,    //聲明當前字段數據類型
        required:true,  //聲明當前字段是否必傳
        unique:true     //聲明當前字段是否唯一
    },
    age:Number,
    sex:{
        type:String,
        default:"未知" //聲明當前字段的默認值
    },
    roles:[String],    //聲明當前字段數據類型為數組, 內部子元素的類型必須是String
    info:mongoose.Schema.Types.Mixed
})

//3.創建模型對象(Model)
//第一個實參->集合名稱
//第二個實參->約束對象
let starsModel = mongoose.model('stars',starsSchema);

//C->create ,是個promise // starsModel.create({
//     name:"雞你太美",
//     age:9.99,
//     sex:"男孩子",
//     roles:["NBA形象大使"],
//     info:"cxk"
// })
//     .then(function(){
//         console.log("添加成功")
//     })

//R->read
// starsModel.find({age:17.99})
//     .then(function(res){
//         console.log(res)
//     })
// starsModel.findOne({age:17.99})
//     .then(function(res){
//         console.log(res)
//     })

// U->update
// starsModel.updateMany({age:17.99},{$set:{age:37.99}})
//     .then(function(res){
//         console.log(res)
//     })
// starsModel.updateOne({age:37.99},{$set:{age:27.99}})
//     .then(function(res){
//         console.log(res)
//     })

// D->delete
// starsModel.remove({sex:"男孩子"})
//     .then(function(res){
//             console.log(res)
//         })

 

 

 

 

 

required: true 必傳字段
minlength:3 字符串最小長度
maxlength: 20 字符串最大長度
min: 2 數值最小為2
max: 100 數值最大為100
enum: ['html', 'css', 'javascript', 'node.js']
trim: true 去除字符串兩邊的空格
validate: 自定義驗證器
default: 默認值
// 引入mongoose第三方模塊 用來操作數據庫
const mongoose = require('mongoose');
// 數據庫連接
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true})
    // 連接成功
    .then(() => console.log('數據庫連接成功'))
    // 連接失敗
    .catch(err => console.log(err, '數據庫連接失敗'));

const postSchema = new mongoose.Schema({
    title: {
        type: String,
        // 必選字段
        required: [true, '請傳入文章標題'],
        // 字符串的最小長度
        minlength: [2, '文章長度不能小於2'],
        // 字符串的最大長度
        maxlength: [5, '文章長度最大不能超過5'],
        // 去除字符串兩邊的空格
        trim: true
    },
    age: {
        type: Number,
        // 數字的最小范圍
        min: 18,
        // 數字的最大范圍
        max: 100
    },
    publishDate: {
        type: Date,
        // 默認值
        default: Date.now
    },
    category: {
        type: String,
        // 枚舉 列舉出當前字段可以擁有的值
        enum: {
            values: ['html', 'css', 'javascript', 'node.js'],
            message: '分類名稱要在一定的范圍內才可以'
        }
    },
    author: {
        type: String,
        validate: {
            validator: v => {
                // 返回布爾值
                // true 驗證成功
                // false 驗證失敗
                // v 要驗證的值
                return v && v.length > 4
            },
            // 自定義錯誤信息
            message: '傳入的值不符合驗證規則'
        }
    }
});

const Post = mongoose.model('Post', postSchema);

Post.create({title:'aa', age: 60, category: 'java', author: 'bd'})
    .then(result => console.log(result))
    .catch(error => {
        // 獲取錯誤信息對象,數組
        const err = error.errors;
        // 循環錯誤信息對象
        for (var attr in err) {
            // 將錯誤信息打印到控制台中
            console.log(err[attr]['message']);
        }
    })

 

 

 

通常不同集合的數據之間是有關系的,例如文章信息和用戶信息存儲在不同集合中,但文章是某個用戶發表的,要查詢文章的所有信息包括發表用戶,就需要用到集合關聯。

使用id對集合進行關聯
使用populate方法進行關聯集合查詢

 

 

// 引入mongoose第三方模塊 用來操作數據庫
const mongoose = require('mongoose');
// 數據庫連接
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true})
    // 連接成功
    .then(() => console.log('數據庫連接成功'))
    // 連接失敗
    .catch(err => console.log(err, '數據庫連接失敗'));

// 用戶集合規則
const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true
    }
});
// 文章集合規則
const postSchema = new mongoose.Schema({
    title: {
        type: String
    },
    // Post和User集合進行關聯
 author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
});
// 用戶集合
const User = mongoose.model('User', userSchema);
// 文章集合
const Post = mongoose.model('Post', postSchema);

// 創建用戶
// User.create({name: 'itheima'}).then(result => console.log(result));
// 創建文章
// Post.create({titile: '123', author: '5c0caae2c4e4081c28439791'}).then(result => console.log(result));
//聯合查詢
Post.find().populate('author').then(result => console.log(result))

打印結果

 

 

 

 

搭建網站服務器,實現客戶端與服務器端的通信
連接數據庫,創建用戶集合,向集合中插入文檔
當用戶訪問/list時,將所有用戶信息查詢出來
將用戶信息和表格HTML進行拼接並將拼接結果響應回客戶端
當用戶訪問/add時,呈現表單頁面,並實現添加用戶信息功能
當用戶訪問/modify時,呈現修改頁面,並實現修改用戶信息功能
當用戶訪問/delete時,實現用戶刪除功能

提前將這些數據導入mogodb數據庫playground中的User集合中

{"_id":{"$oid":"5c09f1e5aeb04b22f8460965"},"name":"張三","age":20,"hobbies":["足球","籃球","橄欖球"],"email":"zhangsan@itcast.cn","password":"123456"}
{"_id":{"$oid":"5c09f236aeb04b22f8460967"},"name":"李四","age":10,"hobbies":["足球","籃球"],"email":"lisi@itcast.cn","password":"654321"}
{"_id":{"$oid":"5c09f267aeb04b22f8460968"},"name":"王五","age":25,"hobbies":["敲代碼"],"email":"wangwu@itcast.cn","password":"123456"}
{"_id":{"$oid":"5c09f294aeb04b22f8460969"},"name":"趙六","age":50,"hobbies":["吃飯","睡覺","打豆豆"],"email":"zhaoliu@itcast.cn","password":"123456"}
{"_id":{"$oid":"5c09f2b6aeb04b22f846096a"},"name":"王二麻子","age":32,"hobbies":["吃飯"],"email":"wangermazi@itcast.cn","password":"123456"}
{"_id":{"$oid":"5c09f2d9aeb04b22f846096b"},"name":"狗蛋","age":14,"hobbies":["打豆豆"],"email":"goudan@163.com","password":"123456"}

從數據庫中獲取數據,然后將數據填充 到模板中,返回html給瀏覽器,俗稱ssr渲染

app.js

// 搭建網站服務器,實現客戶端與服務器端的通信
// 連接數據庫,創建用戶集合,向集合中插入文檔
// 當用戶訪問/list時,將所有用戶信息查詢出來
//     實現路由功能
//     呈現用戶列表頁面
//     從數據庫中查詢用戶信息 將用戶信息展示在列表中
// 將用戶信息和表格HTML進行拼接並將拼接結果響應回客戶端
// 當用戶訪問/add時,呈現表單頁面,並實現添加用戶信息功能
// 當用戶訪問/modify時,呈現修改頁面,並實現修改用戶信息功能
//     修改用戶信息分為兩大步驟
//         1.增加頁面路由 呈現頁面
//             1.在點擊修改按鈕的時候 將用戶ID傳遞到當前頁面
//             2.從數據庫中查詢當前用戶信息 將用戶信息展示到頁面中
//         2.實現用戶修改功能
//             1.指定表單的提交地址以及請求方式
//             2.接受客戶端傳遞過來的修改信息 找到用戶 將用戶信息更改為最新的
// 當用戶訪問/delete時,實現用戶刪除功能

const http = require('http');

const url = require('url');
const querystring = require('querystring');

require('./model/index.js'); // 導入數據庫集合模塊
const User = require('./model/user'); // 創建服務器
const app = http.createServer();

// 為服務器對象添加請求事件
app.on('request', async (req, res) => {
    // 請求方式
    const method = req.method;
    // 請求地址,query為路由路徑?后攜帶的參數如id, 默認是字符串,后面加個true,轉換為對象
    const { pathname, query } = url.parse(req.url, true); if (method == 'GET') {
        // 呈現用戶列表頁面
        if (pathname == '/list') {
            // 查詢用戶信息,返回數組
            let users = await User.find();
            // html字符串
            let list = `
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>用戶列表</title>
                    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
                </head>
                <body>
                    <div class="container">
                        <h6>
                            <a href="/add" class="btn btn-primary">添加用戶</a>
                        </h6>
                        <table class="table table-striped table-bordered">
                            <tr>
                                <td>用戶名</td>
                                <td>年齡</td>
                                <td>愛好</td>
                                <td>郵箱</td>
                                <td>操作</td>
                            </tr>
            `;

            // 對數據進行循環操作
            users.forEach(item => {
                list += `
                    <tr>
                        <td>${item.name}</td>
                        <td>${item.age}</td>
                        <td>
                `;

                item.hobbies.forEach(item => {
                    list += `<span>${item}</span>`;
                })

                list += `</td>
                        <td>${item.email}</td>
                        <td>
                            <a href="/remove?id=${item._id}" class="btn btn-danger btn-xs">刪除</a>
                            <a href="/modify?id=${item._id}" class="btn btn-success btn-xs">修改</a>
                        </td>
                    </tr>`;
            });

            list += `
                        </table>
                    </div>
                </body>
                </html>
            `;
            // 返回一個html給瀏覽器
            res.end(list);
        }else if (pathname == '/add') {
            // 呈現添加用戶表單頁面
            let add = `
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>用戶列表</title>
                    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
                </head>
                <body>
                    <div class="container">
                        <h3>添加用戶</h3>
                        <form method="post" action="/add">
                          <div class="form-group">
                            <label>用戶名</label>
                            <input name="name" type="text" class="form-control" placeholder="請填寫用戶名">
                          </div>
                          <div class="form-group">
                            <label>密碼</label>
                            <input name="password" type="password" class="form-control" placeholder="請輸入密碼">
                          </div>
                          <div class="form-group">
                            <label>年齡</label>
                            <input name="age" type="text" class="form-control" placeholder="請填寫郵箱">
                          </div>
                          <div class="form-group">
                            <label>郵箱</label>
                            <input name="email" type="email" class="form-control" placeholder="請填寫郵箱">
                          </div>
                          <div class="form-group">
                            <label>請選擇愛好</label>
                            <div>
                                <label class="checkbox-inline">
                                  <input type="checkbox" value="足球" name="hobbies"> 足球
                                </label>
                                <label class="checkbox-inline">
                                  <input type="checkbox" value="籃球" name="hobbies"> 籃球
                                </label>
                                <label class="checkbox-inline">
                                  <input type="checkbox" value="橄欖球" name="hobbies"> 橄欖球
                                </label>
                                <label class="checkbox-inline">
                                  <input type="checkbox" value="敲代碼" name="hobbies"> 敲代碼
                                </label>
                                <label class="checkbox-inline">
                                  <input type="checkbox" value="抽煙" name="hobbies"> 抽煙
                                </label>
                                <label class="checkbox-inline">
                                  <input type="checkbox" value="喝酒" name="hobbies"> 喝酒
                                </label>
                                <label class="checkbox-inline">
                                  <input type="checkbox" value="燙頭" name="hobbies"> 燙頭
                                </label>
                            </div>
                          </div>
                          <button type="submit" class="btn btn-primary">添加用戶</button>
                        </form>
                    </div>
                </body>
                </html>
            `;
            res.end(add)
        }else if (pathname == '/modify') {
            // 查詢對應的數據
            let user = await User.findOne({_id: query.id});
            let hobbies = ['足球', '籃球', '橄欖球', '敲代碼', '抽煙', '喝酒', '燙頭', '吃飯', '睡覺', '打豆豆']
            console.log(user)
            // 呈現修改用戶表單頁面
            let modify = `
                <!DOCTYPE html>
                <html lang="en">
                <head>
                    <meta charset="UTF-8">
                    <title>用戶列表</title>
                    <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css">
                </head>
                <body>
                    <div class="container">
                        <h3>修改用戶</h3>
                        <form method="post" action="/modify?id=${user._id}">
                          <div class="form-group">
                            <label>用戶名</label>
                            <input value="${user.name}" name="name" type="text" class="form-control" placeholder="請填寫用戶名">
                          </div>
                          <div class="form-group">
                            <label>密碼</label>
                            <input value="${user.password}" name="password" type="password" class="form-control" placeholder="請輸入密碼">
                          </div>
                          <div class="form-group">
                            <label>年齡</label>
                            <input value="${user.age}" name="age" type="text" class="form-control" placeholder="請填寫郵箱">
                          </div>
                          <div class="form-group">
                            <label>郵箱</label>
                            <input value="${user.email}" name="email" type="email" class="form-control" placeholder="請填寫郵箱">
                          </div>
                          <div class="form-group">
                            <label>請選擇愛好</label>
                            <div>
                                
                            
            `;

            hobbies.forEach(item => {
                // 判斷當前循環項在不在用戶的愛好數據組,checked,選中
                let isHobby = user.hobbies.includes(item);
                if (isHobby) {
                    modify += `
                        <label class="checkbox-inline">
                          <input type="checkbox" value="${item}" name="hobbies" checked> ${item}
                        </label>
                    `
                }else {
                    modify += `
                        <label class="checkbox-inline">
                          <input type="checkbox" value="${item}" name="hobbies"> ${item}
                        </label>
                    `
                }
            })

            modify += `
                            </div>
                          </div>
                          <button type="submit" class="btn btn-primary">修改用戶</button>
                        </form>
                    </div>
                </body>
                </html>
            `;
            res.end(modify)
        }else if (pathname == '/remove') {
            // res.end(query.id)
            // 通過id,刪除一個
            await User.findOneAndDelete({_id: query.id});
            res.writeHead(301, {
                Location: '/list'
            });
            res.end();
        }
    }else if (method == 'POST') {
        // 用戶添加功能
        if (pathname == '/add') {
            // 接受用戶提交的信息
            let formData = '';
            // 接受post參數,流式接收
            req.on('data', param => {
                formData += param;
            })
            // post參數接受完畢
            req.on('end', async () => {
                // 將接收的post參數,字符串轉為對象形式
                let user = querystring.parse(formData)
                // 將用戶提交的信息添加到數據庫中
                await User.create(user);
                // 301代表重定向
                // location 跳轉地址
                res.writeHead(301, { Location: '/list' });
                res.end();
            })
        }else if (pathname == '/modify') {
            // 接受用戶提交的信息
            let formData = '';
            // 接受post參數,流式接收參數
            req.on('data', param => {
                formData += param;
            })
            // post參數接受完畢
            req.on('end', async () => {
                // 轉換成對象形式
                let user = querystring.parse(formData)
                // 將用戶提交的信息跟新到數據庫中
                await User.updateOne({_id: query.id}, user);
                // 301代表重定向
                // location 跳轉地址
                res.writeHead(301, {
                    Location: '/list'
                });
                res.end();
            })
        }
    }

});
// 監聽端口
app.listen(3000);

model--》index.js, 連接數據庫

const mongoose = require('mongoose');
// 數據庫連接 27017是mongodb數據庫的默認端口
mongoose.connect('mongodb://localhost/playground', { useNewUrlParser: true })
    .then(() => console.log('數據庫連接成功'))
    .catch(() => console.log('數據庫連接失敗'));

model-->user.js, 創建數據庫集合

const mongoose = require('mongoose');
// 創建用戶集合規則
const userSchema = new mongoose.Schema({
    name: {
        type: String,
        required: true,
        minlength: 2,
        maxlength: 20
    },
    age: {
        type: Number,
        min: 18,
        max: 80
    },
    password: String,
    email: String,
    hobbies: [ String ]
});

// 創建集合 返回集合構造函數
const User = mongoose.model('User', userSchema);

module.exports = User;

 

第一步(數據查詢),用戶地址欄輸入/list路徑,返回html頁面給瀏覽器

 

 第二步(添加用戶),點擊添加用戶按鈕連接,a標簽,get請求,跳轉到/add, 收集好參數,點擊添加用戶按鈕,form表單,重定向到/list,post請求,查看是否增加用戶成功

 

 

第三部(修改用戶),在/list,點擊修改按鈕,a標簽,跳轉到/modify, 並將用戶id傳遞過去,填寫數據后,點擊修改用戶按鈕,form表單,post請求攜帶用戶id參數,用戶數據庫根據id跟新數據,然后重定向/list,查看修改用戶數據是否成功

 

 第四部分(修改用戶),點擊刪除按鈕,a標簽,get請求,跳轉到/remove,並攜帶用戶id參數,數據庫根據id去刪除該用戶,並跳轉到/list,是否刪除成功

總結,返回的html用字符串拼接,太麻煩,需要用到模板引擎就就簡便了

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM