express框架+mongodb簡易學生管理

weixin_43741547發表於2020-12-30

1、先建立資料庫,再建立集合,用到了資料庫圖形介面Robo 3T,資料集合如下所示:

在這裡插入圖片描述

2、安裝express腳手架

	npm i express-generator -g  //在終端中輸入

3、建立專案

	express stuSystem //執行完成之後根據提示執行以下內容:
	cd stuSystem   //進入stuSystem這個目錄
	npm install   //安裝相關的依賴包
	npm start     //伺服器執行開始

4、在瀏覽器中輸入http://localhost:3000/,結果如下:

在這裡插入圖片描述

5、進行完第4步,就搭建好了專案,專案的目錄結構如下:

	- app.js:入口檔案
	- bin:二進位制目錄
	- node_modules:依賴包
	- package.json:依賴包的記錄檔案
	- public:靜態目錄
	- routes:路由
	- views:頁面模板

6、現在開始建立學生管理系統相關的檔案:

  • 在public資料夾下建立一個index.html檔案 (public是專門用來管理靜態資源的,在public下建立index.html,express就會自動訪問到它),伺服器一啟動就執行。
  • 在routes路由這個資料夾建stu.js檔案,用於接收前端ajax請求,以及返回響應資料
  • 修改app.js檔案的有關內容(app.js檔案是生成專案就有的)
	var stuRouter = require('./routes/stu');//在路由這個資料夾下面建立了stu.js檔案,在這裡通過require()引入這個檔案,定義一個stuRouter變數來得到
	app.use('/stu', stuRouter); //註冊中介軟體stuRouter
  • 在目錄中建立Service資料夾,建立stuService.js檔案
  • 在目錄中建立Dao資料夾,建立stuDao.js檔案、db.js檔案以及Model資料夾,再在Model下建立stuModel.js檔案

整體檔案如下:
在這裡插入圖片描述

7、上面介紹了專案大體的檔案,接下來是具體的內容,具體的內容涉及到兩個知識點:

  • Restful(表現層狀態轉移)
    • Restful就是規範url,url本身就是標誌資源的,不應該標誌這個資源要做什麼,例如下面兩條url都是標誌刪除資源的操作
      http://abc.com/?method=comment.del&id=XXX
      http://abc.com/comment/del/xxx
    
    • 所以應該使用 http不同的請求方式來表達要對一個資源做什麼事情:
      - 新增:【POST】http://abc.com/comment
      - 查詢:【GET】http://abc.com/comment/x
      - 刪除:【DELETE】http://abc.com/comment/x
      - 修改:【PUT】http://abc.com/comment/x
    
  • 三層架構
    • 表示層: 主要對使用者的請求接受,以及資料的返回,為客戶端提供應用程式的訪問。
    • 業務邏輯層: 主要負責對資料層的操作。也就是說把一些資料層的操作進行組合。
    • 資料訪問層: 主要看資料層裡面有沒有包含邏輯處理,實際上它的各個函式主要完成各個對資料檔案的操作。而不必管其他操作。
    • 具體的實現就是目錄表中對應的資料夾:
      - routes:表現層
      - service:業務層
      - dao:持久層
    

8、具體檔案內容:

index.html

//這是html部分
	<div class="container">
        <h1>學生管理系統</h1>
        <form>
            <!-- 姓名 -->
            <div>
                <label for="name">姓名:</label>
                <input type="text" name="name" id="name">
            </div>
            <!-- 年齡 -->
            <div>
                <label for="age">年齡:</label>
                <input type="text" name="age" id="age">
            </div>
            <!-- 性別 -->
            <div>
                <label for="gender">性別:</label>
                <input type="radio" name="gender" value="" id="male" checked><input type="radio" name="gender" value="" id="female"></div>
            <!-- 分數 -->
            <div>
                <label for="score">分數:</label>
                <input type="text" name="score" id="score">
            </div>
            <!-- 提交、重置 -->
            <div class="btn">
                <input type="button" value="提交" class="submitBtn">
                <input type="reset" value="重置" class="reset">
            </div>
        </form>

        <h2>學生資訊表</h2>
        <table></table>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
//javascript部分
	<script>
        let id =0;
        // 渲染表格的render函式
        function render(arr) {
            $('table').html('');
            let tHead = `
                <tr>
                    <th>學生姓名</th>
                    <th>學生年齡</th>
                    <th>學生性別</th>
                    <th>學生分數</th>
                    <th>操作</th>
                </tr>
            `;

            let tBody = arr.map(item => {
                return `
                    <tr>
                        <td>${item.name}</td>
                        <td>${item.age}</td>
                        <td>${item.gender}</td>
                        <td>${item.score}</td>
                        <td> 
                            <button class="editBtn" data-id=${item._id}>修改</button>
                            <button class="delBtn" data-id=${item._id}>刪除</button>
                        </td>
                    </tr>
                `
            }).join('');
            $("table").html(tHead + tBody);
        }

        // 傳送請求到後端得到資料庫資料
        const stuInfo = function () {
            $.ajax({
                url: '/stu',
                type: 'GET',
                success: function (data) {
                    render(data);
                }
            })
        };
        stuInfo();

        // submit按鈕繫結點選事件,(既是提交也是修改)
        $(".submitBtn").on('click', function () {
            let data = $("form").serializeArray();
            if (data.every(item => {
                    return item.value !== ''
                })) {
                // 根據提交按鈕的文字來判定使用者是做新增還是修改
                if ($(".submitBtn").val() === '提交') {
                    // 新增操作
                    $.ajax({
                        url: '/stu',
                        type: 'POST',
                        data: $('form').serialize(),
                        success: function (data) {
                            $('form')[0].reset();
                            stuInfo();
                        }
                    })
                } else {
                    // 修改操作
                    $.ajax({
                        url: '/stu',
                        type: 'PUT',
                        data: {
                            id,
                            info: $('form').serialize()},
                        success: function (data) {
                            $('form')[0].reset();
                            $('.submitBtn').val('提交');
                            stuInfo();
                        }
                    })
                }
            } else {
                window.alert("不能為空!!!!")
            }
        })

        // 獲取一個學生資訊
        const oneStuInfo=async function(id){
            return new Promise((resolve,reject)=>{
                $.ajax({
                    url:'/stu/findOneStu',
                    type:'GET',
                    data:{id},
                    success:function(data){
                        resolve(data);
                    }
                })
            })
        }

        // 刪除(事件委託)
        $('table').on('click','.delBtn',async function(e){
            let data=await oneStuInfo(e.target.dataset.id);
            if(window.confirm(`你確定要刪除此學生嗎?
                學生姓名:${data[0].name}
                學生年齡:${data[0].age}
                學生性別:${data[0].gender}
                學生分數:${data[0].score}
            `)){
                $.ajax({
                    url:'/stu',
                    type:'DELETE',
                    data:{id:e.target.dataset.id},
                    success:function(){
                        stuInfo();
                    }
                });
            }
        });

        //修改(事件委託)
        $('table').on("click",".editBtn",async function(e){
            let data=await oneStuInfo(e.target.dataset.id);
            id=e.target.dataset.id;
            // 將資料進行回填
            $('#name').val(data[0].name); 
            $('#age').val(data[0].age); 
            if(data[0].gender==='男'){
                $('#male').prop('checked',true);
            }else{
                $('#female').prop('checked',true);
            }
            $('#score').val(data[0].score); 
            $('.submitBtn').val("修改");
        })
    </script> 	

stu.js

// 表現層
//在這裡就用到了Restful(表現層狀態轉移)
var express = require('express');
var router = express.Router();

const {findStuService,addStuService,findOneStuService,delStuService,editStuService} = require('../Service/stuService');

router.get('/', async function (req, res, next) {
  res.send(await findStuService());
});

// 增加學生
router.post('/', async function (req, res, next) {
  res.send(await addStuService(req.body));
});


// 獲取一個學生資訊
router.get('/findOneStu', async function (req, res, next) {
  res.send(await findOneStuService(req.query.id));
});

// 刪除學生資訊
router.delete('/', async function (req, res, next) {
  res.send(await delStuService(req.body.id));
});

// 修改學生資訊
router.put('/', async function (req, res, next) {
  console.log(req.body);
  res.send(await editStuService(req.body));
});

module.exports = router; 	

stuService.js

// 這一層就是業務層
const urlencode = require('urlencode');
const {findStuDao,addStuDao,findOneStuDao,delStuDao,editStuDao} = require('../Dao/stuDao');
// 查詢所有進行渲染表格
module.exports.findStuService = async function(){
    console.log(findStuDao,'func')
    return await findStuDao()
}

// 增加學生
module.exports.addStuService = async function(newStu){
    return await addStuDao(newStu)
}

// 獲取一個學生資訊
module.exports.findOneStuService = async function(id){
    return await findOneStuDao(id);
}

// 刪除學生資訊
module.exports.delStuService = async function(id){
    return await delStuDao(id);
}


// 修改學生資訊
module.exports.editStuService = async function(stu){
    // 'name=%E5%90%8E%E5%A4%A9&age=44&gender=%E7%94%B7&score=34'
    let stuInfo=urlencode.decode(stu.info).split('&').map(item=>{
        return item.split('=');
    });
    let data={};
    for(let i of stuInfo){
        data[i[0]]=i[1];  //鍵=值
    }
    data.id=stu.id;
    return await editStuDao(data);
}

	

stuDao.js

//持久層
const stuModel = require('./Model/stuModel');
// 查詢所有進行渲染表格
module.exports.findStuDao = async function () {
    return await stuModel.find();
}

// 增加學生
module.exports.addStuDao = async function (newStu) {
    console.log(newStu);
    return await stuModel.create(newStu);
}

// 獲取一個學生資訊
module.exports.findOneStuDao = async function (id) {
    return await stuModel.find({_id : id});
}

// 刪除學生資訊
module.exports.delStuDao = async function (id) {
    return await stuModel.deleteOne({_id : id}); 
}

// 修改學生資訊
module.exports.editStuDao = async function(stu){
    // {"name":"xiejie"},{"name" : "謝傑"}
    console.log(stu);
    return await stuModel.updateOne({_id : stu.id},stu);
}
	

stuModel.js

// stuModel.js是資料模型檔案
require('../db.js')
const mongoose = require('mongoose');

// 1. 建立 Schema,Schema 就是我們資料模型的骨架
// 在建立 Schema,就需要和集合(表)進行對應
const stuSchema = new mongoose.Schema({
    name: String,
    age: Number,
    gender: String,
    score:Number
},{versionKey:false});

// 2. 根據上面建立的 Schema 來生成資料模型
// (1) model 的名字 (2)定義的 Schema (3)和資料庫的哪個集合關聯
mongoose.model('stuModel', stuSchema, 'student');//相對應的集合

// 3. 將這個模型匯出去,後面所有的操作(增刪改查)都是基於這個模型
module.exports = mongoose.model('stuModel');

db.js

// 這個檔案負責書寫連線資料庫的相關配置
const mongoose = require('mongoose');
const dbURI = 'mongodb://localhost/students'; // 配置要連線的資料庫

mongoose.connect(dbURI,{useNewUrlParser : true, useUnifiedTopology : true});

mongoose.connection.on('connected',()=>{
    console.log('資料庫已經連線...');
})

9、最後效果如下:

在這裡插入圖片描述

相關文章