0


Node.js | 基于 MongoDB 的简易用户管理系统

在这里插入图片描述


🖥️ NodeJS专栏:Node.js从入门到精通
🖥️ 博主的前端之路(源创征文一等奖作品):前端之行,任重道远(来自大三学长的万字自述)
🖥️ TypeScript知识总结:TypeScript 学习笔记(十万字超详细知识点总结)
🧑‍💼 个人简介:大三学生,一个不甘平庸的平凡人🍬
👉 你的一键三连是我更新的最大动力❤️!


📑目录


🔽 前言

上一节我们介绍了

MongoDB

Mongoose

,这一节为了巩固

Nodejs

操作

MongoDB

数据库实现增删改查的功能,本文将带领大家制作一个简易的用户管理系统项目,让我们开始吧!

1️⃣ 项目最终效果

在带领大家搭建项目之前,先向大家展示一下项目最终实现的效果:

在这里插入图片描述

因为写这个项目的目的是巩固Nodejs操作数据库,重点在于功能的实现,所以我们并不会过多的去写

CSS

来美化页面。

这个简易的用户管理系统包含以下功能:

  • 添加用户信息
  • 分页查询用户信息(不查询密码字段)
  • 修改用户信息
  • 删除用户信息

2️⃣ 搭建项目

我们将使用

express 应用程序生成器

来搭建项目骨架,控制台输入:

express 简易用户管理系统 --view=ejs

上面的命令将创建一个使用

ejs

模板的名为

简易用户管理系统

express

项目。

express 应用程序生成器

的介绍可以查看我的这篇文章:Node.js | 深入讲解 express 应用程序生成器

使用VS Code打开项目,找到

package.json

,修改下图所示的地方:

在这里插入图片描述

这里修改的目的是:在启动项目时使用

nodemon

指令来启动,这样当我们项目代码更改时它能够自动重新运行(前提是你安装了

nodemon

指令,没有安装的可以控制台输入

npm i nodemon -g

全局安装

nodemon

)。

之后安装

mongoose

,在项目根目录下打开终端执行下面这行代码进行安装:

npm i mongoose

再执行以下代码运行项目:

npm run start

浏览器打开

http://localhost:3000/

,出现以下页面表示运行成功:

在这里插入图片描述

3️⃣ 连接MongoDB

🔹 配置MongoDB

项目根目录下创建

config

文件夹(此文件夹用来存放配置文件),并在此文件夹内创建

db.config.js

文件(

DB

数据的配置文件):

// db.config.jsconst mongoose =require("mongoose");// 连接数据库// 前缀mongodb:是固定的,后面是你的mongodb的运行端口// user_test代表数据库名称
mongoose.connect("mongodb://127.0.0.1:27017/user_test");// 当你插入集合和数据时,数据库user_test会自动创建
user_test

是我定义的数据库的名称,大家根据需要可以自行更改。

之后在

app.js

文件中引入我们创建的这个

db.config.js

文件:

// app.js中添加以下代码// 引入数据库模块require("./config/db.config");

🔹 创建用户模型

项目根目录下创建

model

文件夹(此文件夹用来存放模型),并在此文件夹内创建

UserModel.js

文件(用户模型):

// UserModel.jsconst mongoose =require("mongoose");// 字段类型const UserType ={username: String,password: String,age: Number,};// 创建一个模型(user),对应数据库中的集合(表)(users)const UserModel = mongoose.model("user",newmongoose.Schema(UserType));// 注意:创建的mongodb的集合名称是加s的// mongoose.model第二个参数可以通过mongoose.Schema生成的实例来限制集合字段类型// 因为mongodb过于自由,对类型没有限制,我们在开发中往往需要使用mongoose.Schema来手动限制数据库各种字段类型// 导出模型
module.exports = UserModel;

根据这个用户模型,

Mongoose

能够自动帮我们在数据库中创建一个

users

集合,集合内的每条数据包含的字段有:

username

password

age

、以及自动生成的

_id

之后运行

MongoDB

数据库,再启动项目,

MongoDB

的运行窗口出现下图所示就代码我们连接成功了:

在这里插入图片描述

4️⃣ 创建API接口

app.js

中的

usersRouter

的路由前缀修改为

/api

// app.use("/users", usersRouter); 
app.use("/api", usersRouter);// 使用/api前缀

routes

目录下的

users.js

中引入我们上面创建的用户模型:

// users.js// 引入用户模型const UserModel =require("../model/UserModel");

再将

users.js

中的下述代码删除:

/* GET users listing. */
router.get("/",function(req, res, next){
    res.send("respond with a resource");});

🔹 接口规范

我们常使用

RES Tful

架构来规范接口的定义,

RES Tful

特点包括:

  1. 每一个URI代表1种资源;
  2. 客户端使用GETPOSTPUTDELETE4个表示操作方式的动词对服务端资源进行操作:GET用来获取资源,POST用来新建资源(也可以用于更新资源),PUT用来更新资源,DELETE用来删除资源;
  3. 通过操作资源的表现形式来操作资源;
  4. 资源的表现形式是XML或者HTML
  5. 客户端与服务端之间的交互在请求之间是无状态的,从客户端到服务端的每个请求都必须包含理解请求所必需的信息。

使用方式:
请求方式请求地址效果GEThttp://localhost:3000/api/user获取用户列表(所有用户信息)GEThttp://localhost:3000/api/user/{id}获取指定id的用户信息POSThttp://localhost:3000/api/user添加用户信息PUThttp://localhost:3000/api/user/{id}修改指定id的用户信息DELETEhttp://localhost:3000/api/user/{id}删除指定id的用户信息
过滤信息:

过滤信息常用于

GET

请求,通过指定一些规则来获取对应的信息。

通用字段说明例子limit返回记录的数量http://localhost:3000/api/user/?limit=10 获取10条数据offset返回记录的开始位置http://localhost:3000/api/user/?offset=10 获取数据库中第10条之后的数据page指定第几页常配合per_page使用per_page每页的记录数http://localhost:3000/api/user/?page=2&per_page=10 按照每页10条数来算,获取第二页数据sortby指定返回结果按照哪个属性排序常配合order使用order指定排序顺序http://localhost:3000/api/user/?sortby=name&order=asc 获取按照name字段升序排序的数据state指定筛选条件http://localhost:3000/api/user/?state=close 获取state为close的数据
多个过滤字段可以相互结合使用(通过

&

分割),并以

URL

参数的形式出现在请求地址之后。

🔹 添加用户信息

添加用户信息我们使用

post

接口,

users.js

中添加以下代码:

// 添加数据
router.post("/user",function(req, res, next){// 获取请求体中的参数const{ username, password, age }= req.body;// 插入数据库
    UserModel.create({ username, password, age }).then((data)=>{
            res.send(data);}).catch((error)=>{
            console.log(error);
            res.send({mag:"添加信息出错!"});});});

使用

Api

调试工具测试一下接口是否正常运行,这里使用

Apifox

进行测试:

Apifox的使用教程

先将测试环境的前置

URL

设置为我们项目运行的地址:

在这里插入图片描述

http://127.0.0.1:3000就是http://localhost:3000/

定义接口运行接口在这里插入图片描述在这里插入图片描述
结果显示接口运行成功,在

MongoDB

可视化工具中能够查看到新添加的数据:

在这里插入图片描述

🔹 删除用户信息

删除用户信息我们使用

delete

接口,

users.js

中添加以下代码:

// 删除数据
router.delete("/user/:userId",function(req, res, next){// 获取动态路由参数const{ userId }= req.params;// 删除数据
    UserModel.deleteOne({_id: userId }).then((data)=>{
            res.send({msg:"删除成功!",...data });}).catch((error)=>{
            console.log(error);
            res.send({msg:"删除失败!"});});});

使用

Apifox

测试:
定义接口运行接口效果在这里插入图片描述在这里插入图片描述在这里插入图片描述

🔹 修改用户信息

修改用户信息我们使用

put

接口,

users.js

中添加以下代码:

// 修改数据// 动态路由,获取前端传来的id
router.put("/user/:userId",function(req, res, next){// 获取请求体中的参数const{ username, password, age }= req.body;// 获取动态路由参数const{ userId }= req.params;// 更新数据
    UserModel.updateOne({_id: userId },{
            username,
            password,
            age,}).then((data)=>{
            res.send({msg:"更新成功!",...data });}).catch((error)=>{
            console.log(error);
            res.send({msg:"更新失败!"});});});

使用

Apifox

测试,定义接口:
定义接口运行接口效果在这里插入图片描述在这里插入图片描述在这里插入图片描述

🔹 查询用户信息

查询用户信息使用

get

接口,

users.js

中添加以下代码:

这里的查询先是获取到数据的总数量,然后再根据前端传来的

page

limit

字段查询到指定数据,之后将查询的数据和数据总数量一并返回给前端,从而实现分页查询的功能。

// 查询数据:分页查询的接口
router.get("/user",function(req, res, next){// 获取路由参数(过滤信息)const{ page, per_page}= req.query;
    UserModel.find().count()// count方法,获取数据的总数量.then((dataCount)=>{// find查询,第二个参数数组指定获取的字段,这里是获取username和age以及id(默认具有),不获取password
            UserModel.find({},["username","age"])// sort排序,按照age:1(正序)排序,age:-1为倒叙.sort({age:1})// skip方法,代表跳过几条数据开始获取.skip((page -1)* per_page)// limit方法,代表取多少条数据.limit(per_page).then((data)=>{
                    res.send({ data, dataCount });});});});

定义接口运行接口电脑在这里插入图片描述
至此,整个项目需要用到的Api接口就都定义好了,下面我们开始搭建前端页面。

5️⃣ 搭建前端页面

我们在

views

目录下的

index.ejs

文件中创建我们的前端页面:

注意:虽然我们这个项目是在

ejs

模板中搭建页面,但我们并不需要使用

ejs

语法,只需使用

html

语法即可。

🔹 页面结构

<body><h1>NodeJS操作mongodb:简易用户管理系统</h1><div>
      用户名:<inputtype="text"id="username"></div><div>
      密码:<inputtype="text"id="password"></div><div>
      年龄:<inputtype="number"id="age"></div><buttonid="addBtn">增加用户</button><p>提示:在输入框中输入信息可选择点击增加用户,也可点击表格中更新按钮来更新指定数据</p><hr><tableborder="2"><thead><tr><td>id</td><td>用户名</td><td>年龄</td><td>操作</td></tr></thead><tbody></tbody></table><!-- 存放分页按钮 --><divid="pageBtn"></div><!-- 存放业务代码 --><script></script></body>

🔹 业务代码

获取DOM元素:

const username = document.getElementById('username')const password = document.getElementById('password')const age = document.getElementById('age')const pageBtn = document.getElementById('pageBtn')const addBtn = document.getElementById('addBtn')

定义变量:

// 数据总条数let dataCount =0// 每页显示条目个数let pageSize =2// 当前页数let pageNum =1// 总页数let pageCount =1

渲染列表数据:

// 渲染列表数据functionrenderTable(data){const tbody = document.querySelector('tbody')
  tbody.innerHTML = data.map(item=>`
    <tr>
      <td>${item._id}</td>
      <td>${item.username}</td>
      <td>${item.age}</td>
      <td>
        <button οnclick="deleteFn('${item._id}')">删除</button>
        <button οnclick="updateFn('${item._id}')">更新</button>
      </td>
  
    </tr>
  `).join('')}
renderTable

函数接收的是一个用户数据的数组集合,用来将此数据渲染到

tbody

中。

渲染分页按钮:

// 渲染分页按钮functionrenderPageBtn(page){let str =''for(let i =1; i <= page; i++){if(i === pageNum){// 添加红色背景
      str +=`<button οnclick="getList(${i})" style="background-color: red;">第${i}页</button>`}else{
      str +=`<button οnclick="getList(${i})">第${i}页</button>`}}
  pageBtn.innerHTML = str
}
renderPageBtn

函数接收的参数表示总页数,有多少页就渲染多少个分页按钮,同时对当前所处的页对应的分页按钮做背景变红的处理,并且每个分页按钮都绑定了一个点击事件。

获取数据:

// 查询数据apifunctiongetList(page){fetch(`/api/user/?page=${page}&per_page=${pageSize}`).then(res=> res.json()).then(res=>{// 设置数据总条数
    dataCount = res.dataCount
    // 设置总页数
    pageCount = Math.ceil(dataCount / pageSize)// 设置当前页数
    pageNum = page
    // 渲染列表数据renderTable(res.data)// 渲染分页按钮renderPageBtn(pageCount)})}
getList

函数接收的参数表示页数,用来获取指定页的数据,并调用

renderTable

将数据渲染,同时调用

renderPageBtn

更新分页按钮。

添加数据:

// 添加数据
addBtn.onclick=()=>{if(!(username.value && password.value && age.value)){alert('请正确输入输入框信息!')return}fetch('/api/user',{method:'post',body:JSON.stringify({username: username.value,password: password.value,age: age.value
    }),headers:{"Content-Type":"application/json"}}).then(res=> res.json()).then(res=>{// 添加完成后获取数据库中最新数据getList(pageNum);alert('添加成功!')// 清空表单
    username.value =''
    password.value =''
    age.value =''})}

更新数据:

// 更新数据apifunctionupdateFn(id){if(!(username.value && password.value && age.value)){alert('请正确输入输入框信息!')return}fetch(`/api/user/${id}`,{method:'put',body:JSON.stringify({username: username.value,password: password.value,age: age.value
    }),headers:{"Content-Type":"application/json"}}).then(res=> res.json()).then(res=>{// 添加完成后获取数据库中最新数据getList(pageNum);alert('更新成功!')// 清空表单
    username.value =''
    password.value =''
    age.value =''})}

删除数据:

// 删除数据apifunctiondeleteFn(id){fetch(`/api/user/${id}`,{method:'delete',}).then(res=> res.json()).then(res=>{// 删除完成后获取数据库中最新数据// newPageCount删除完数据后最新的总页数let newPageCount = dataCount >1? Math.ceil((dataCount -1)/ pageSize):1if(pageNum > newPageCount){// 如果当前页数大于总页数则获取最后一页数据getList(newPageCount)}else{getList(pageNum)}alert('删除成功!')})}

至此项目就全部完成啦!项目效果与文章开头展示的一样,项目最终的目录结构如下:

在这里插入图片描述

🔼 结语

经过上面一系列的操作,我们的简易用户管理系统总算是写好了,但这时你会发现我们的这个项目写的好乱,比如

routes

目录本该存放的是单纯的路由文件,但现在它还包含了操作数据库的代码:

在这里插入图片描述

并且这些操作数据库的代码也不是单纯的操作数据库,还掺杂了处理数据,返回数据的代码(如

res.send

),这就使整个项目的业务变得特别混乱。

各部分之间相互掺杂,导致耦合度太高,这势必为之后的维护种下了风险的种子。

我们可以使用MVC架构,实现业务分层来解决这些问题,下一篇我们就将深入去学习

MVC

架构,并使用它来重构这个简易用户管理系统,敬请期待!

博主的Node.js从入门到精通专栏正在持续更新中,关注博主订阅专栏学习Node不迷路!

如果本篇文章对你有所帮助,还请客官一件四连!❤️

在这里插入图片描述

标签: mongodb node.js express

本文转载自: https://blog.csdn.net/m0_51969330/article/details/127653162
版权归原作者 海底烧烤店ai 所有, 如有侵权,请联系我们删除。

“Node.js | 基于 MongoDB 的简易用户管理系统”的评论:

还没有评论