Nodejs三层架构的封装

news2024/11/29 13:34:14

nodejs三层架构开发模式在这里插入图片描述

项目结构
在这里插入图片描述
依次在每个目录添加代码
1.在dao层下创建database.js模块,里面存放的是连接数据库的模块代码

const {connect,connection} = require('mongoose');
// 设置要连接的 MongoDB 服务器地址(studentsManage:要连接的数据库名称)
const dbURI = 'mongodb://localhost:27017/xiaoji';
// 连接数据库
connect(dbURI, { useNewUrlParser: true, useUnifiedTopology: true });
//当数据库连接成功时触发此事件
connection.on('connected', () => console.log(dbURI + ' 数据库连接成功'));

2.在dao包下创建usersModel.js,用于存放我们的模型模块

// const mongoose = require('mongoose');
const {Schema,model} = require('mongoose');

//Schema这个方法是一个构造函数,通过new创建这个构造方法的实例对象
// 这个方法用于定义数据库列名和值的类型
// 1.定义数据集合的结构:定义出集合中数据有哪些属性,属性的值是什么类型。
const usersSchema = new Schema({
    username:String,
    password:Number
//后面以此类推定义列名和列的值类型
})

//2.定义数据集合的模型,将Schema和数据库中的集合关联起来
//model参数一:模型名称
//参数二:为上面的usersSchema
//参数三:数据库中的集合名称
const usersModel=model('usersmodel',usersSchema,'users')

//向外导出模型
module.exports.usersModel=usersModel;

3.在主目录下创建sever.js,这个是核心层,运行服务器启动的就是这个界面,代码如下

// 导入express服务器第三方的包
const express = require("express")
// 创建服务器实例
const app=express()
//导入连接数据库的模块
const users=require('./routes/users.js')

require('./dao/database.js')
app.use(users)
//调用listen启动服务器
app.listen(80, function () {
    console.log("开启了127.0.0.1服务器");
})

建议:
4,5,6都涉及数据的传输,从用户到数据库的数据传输建议直接按照6,5,4顺序看,从6用户传入数据,5接收6的数据再传送给4
从数据库到的用户数据传输建议直接按照4,5,6顺序看,从4数据库传出数据,5接收4的数据再传送给6用户界面

4.在dao包下创建userdao.js模块,这个模块才是真正操作数据库增删改查的模块,这里只演示条件查询用户

//导入模型模块,使用里面的方法进行数据库操作
const {usersModel}=require('./models/usersModel.js')
//这里的user是从5方法userService.js模块传入过来的数据
module.exports.login=async function(user){
	//这里演示查询所有用户,find不传参数为查询所有用户
   const data = await usersModel.find(user)
   //打印一下数据
   console.log('3333',data);
   //在module.exports上导出一个login方法,使外界导入此模块,能通过这个方法,传入数据
}

5.在service包下创建userService.js模块(这个包下的模块用于处理数据,对数据进行判断过滤),在里面导入上面的userdao.js,目的是使用上面的方法给userdao.js模块传入用户数据,代码如下

//通过解构赋值,找到userdao.js向外导出的login方法,在里面传入数据
const {login} = require('../dao/usersdao')

//这里的user是从6方法的users.js(用户)传入过来的
module.exports.login=function(user){
    //调用第三层的方法
    login(user)
}

6.在routers包下创建各种操作的模块,例如老师增删改查模块,学生增删改查模块等等,这里只演示示条件查询用户接口,代码如下

// 导入express服务器第三方的包
const express = require("express")
const router=express.Router()
//导入userService.js模块,目的是通过上面的login方法传给userService.js模块传入数据
const {login}=require('../service/usersService')

router.get("/select",function(req,res){
    const user=req.query;//{username:'zs',password:'456'}
    //这里就是将用户发送来的数据传送给userService.js,再通过userService.js模块传送给usersdao.js模块,最后通过usersdao.js模块对传入的数据进行增删改查操作
    login(user)
})

module.exports=router;

上面配置完开始运行:
本人数据库:

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

数据成功获取

当传入不存在的数据时
在这里插入图片描述
完美运行

下面是数据从数据库到用户界面展现的过程

为了方便清楚数据如何从前往后,从后往前传递的,本人这里分开写—上面从用户到数据库,下面写从数据库到用户

由于数据库是有了数据,对数据进行完增删改查才返回处理好的数据,因此可以理解为,下面数据库到用户的代码为最全的代码,用户—数据库—数据库----用户

这里直接从4开始标号了,因为下面代码存在的模块和上面的4,5,6一样,因为是数据库到用户,所以这里的4对应上面的6,5对应上面的5,6对应上面的4

其实也没大家想的多复杂了,完成用户到数据库传送数据,那数据库将数据处理完返回就行了,因此就一直return就好了

4.usersdao.js里面直接将增删改查的获得的数据库的数据返回给userService.js即可

const {usersModel}=require('./models/usersModel.js')
module.exports.login=async function(user){
   const data = await usersModel.find(user)
   //将处理完的数据返回出去
   return data
}

5.userService.js里面将数据进行处理判断,处理完了返回给users.js(用户界面)

const {login} = require('../dao/usersdao')

module.exports.login=async function(user){
    //调用第三层的方法
    //调用这个login方法得到usersdao.js的数据返回值
    // 因为这个方法是异步的,所以需要async/await处理
    const data=await login(user)
    // 对usersdao.js数据库传来的数据进行处理
    if(data.length>0){
        //说明有数据
        return {
            msg:'获取数据成功',
            status:1,
            data:data
        }
    }else{
        //无数据
        return {
            msg:'获取数据失败',
            status:0
        }
    }
}

6.在users.js获得来自userService.js处理好的数据,并向用户响应数据

// 导入express服务器第三方的包
const express = require("express")
const router=express.Router()
const {login}=require('../service/usersService')

router.get("/select",async function(req,res){
    const user=req.query;//{username:'zs',password:'456'}
    // 同样的,这个login为异步请求,需要用async/await处理数据
   const data=await login(user)
   //将数据响应给用户
   res.send(data)
})
//向外导出路由模块
module.exports=router;

以上都弄完,可以看最终效果图了
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/142366.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Unity InputSystem基础

一些概念 Action Maps 一组Action的集合为一个Action Map。可以同时有多个Action Map,可以进行切换,也可以同时运行(监控)。例如可以使用joystick控制角色移动,也可以使用joystick控制菜单。通过切换Action Map&#x…

别小看 Log 日志,它难住了我们组的架构师

Slf4j slf4j 的全称是 Simple Loging Facade For Java,它仅仅是一个为 Java 程序提供日志输出的统一接口,并不是一个具体的日志实现方案,就比如 JDBC 一样,只是一种规则而已。所以单独的 slf4j 是不能工作的,必须搭配…

Go后端部署服务器

go后端部署服务器方式一:(最简单) 和暑假做重点场所项目部署一样,简单,无脑,手动,麻烦 1、# 修改(确保)环境,因为服务器是linux系统 go env -w GOOSlinux …

FreeRTOS实验使用02

1:队列集使用 主要就是函数xQueueSelectFromSet 返回值的判断,用于判断里面的消息谁有效 Pend (or block) on multiple RTOS queues and semaphores in a set (freertos.org) 官方给的例程更好,更规范 2:任务通知使用 xR xTaskNotify(Task…

手把手教你从0到1通过 Express 完成图片上传并保存至阿里云OSS功能(附详细源码)

🧨 大家好,我是 Smooth,一名大三的 SCAU 前端er 🙌 如文章有误,恳请评论区指正,谢谢! ❤ 写作不易,「点赞」「收藏」「转发」 谢谢支持! 背景 近期一个项目由于缺人&…

遗传算法解决旅行商问题

问题描述旅行商问题(TSP). 一个商人欲从自己所在的城市出发,到若干个城市推销商品,然后回到其所在的城市。如何选择一条周游路线,使得商人经过每个城市一次且仅一次后回到起点,并使他所走过的路径最短&…

oom killer理解和日志分析:知识储备

参考:oom killer 详解 oom killer日志分析,这是前篇,准备一些基础知识 带着问题看: 1.什么是oom killer 是Linux内核设计的一种机制,在内存不足的时候,选择一个占用内存较大的进程并kill掉这个进程&…

【JVM系列】JVM内存结构

JVM内存结构 运行时数据区 JAVA运行时内存划分堆,方法区,虚拟机栈,本地方法栈和程序计数器。 线程私有的有: - 程序计数器 - 虚拟机栈 - 本地方法栈​ 线程共享的有: - 堆 - 方法区程序计数器 用来记录当前线程执…

Redundant Paths(双向图的缩点(边联通分量缩成点))

F-Redundant Paths_2022图论班第二章连通性例题与习题 (nowcoder.com) 为了从F(1 \leq F \leq 5000)F(1≤F≤5000)一块牧场(编号为1..F)到另一块牧场,贝西和牛群的其他成员不得不穿过烂苹果树附近。奶牛现在厌倦了经常被迫走一条特定的路,想要建造一些新…

YOLO-V5 系列算法和代码解析(六)—— 分布式训练

文章目录预备知识DPDDPDP和DDP对比YOLO-V5 实际使用参考链接预备知识 为了更好的理解分布式相关的内容,需要提前熟悉一些基本概念和特定的名称。分布式训练涉及到设备端(CPU,GPU),算法端(梯度更新&#xff…

项目团队承诺管理的3个重要因素

每一个项目都需要一个强有力的领导者,以获得适当的成功机会。与一个优柔寡断、缺乏经验的项目领导者相比,一个有组织的领导者在管理一个精心策划的项目时,更有可能取得项目的成功和客户的满意。再加上一个非常投入和负责任的项目团队&#xf…

[ docker相关知识 ] 删除 docker 拉取的镜像 -- 释放内存

🍬 博主介绍 👨‍🎓 博主介绍:大家好,我是 _PowerShell ,很高兴认识大家~ ✨主攻领域:【渗透领域】【数据通信】 【通讯安全】 【web安全】【面试分析】 🎉点赞➕评论➕收藏 养成习…

Speckle 3d数据引擎Python开发实战

在这个教程中,我们将使用 Speckle 数据并使用它来创建一个超级简单的仪表板。 我们将从Speckle流中接收几何图形,更新数据,并使用它来使用 Plotly 和 Dash 进行一些计算和简单绘图。 我们假设你具有 Python 和 Speckle 的一般知识。 如果有任…

信号处理——MATLAB音频信号加噪、滤波

音频信号叠加噪声及滤波一、前言二、信号分析及加噪三、滤波去噪四、总结很抱歉大家,最近经常有朋友私信问我关于这篇信号处理的一些问题,因为最近比较忙所以没能一一回复,给大家说句抱歉,希望那些给我私信的人可以看到。大家问的…

golang 垃圾回收-三色标记法(白话版)

对于golang 垃圾回收的了解,我理解更多的就是了解,实际做项目能用到垃圾回收的知识点不多,但有些晦涩难懂的语言,是我们的绊脚石,对于技术怎么能理解就怎么记忆。 1. golang垃圾回收的基础:标记&#xff08…

ESNI 和ECH的前世今生

这边文章中提到过虽然 TLS 能够加密整个通信过程,但是在协商的过程中依旧有很多隐私敏感的参数不得不以明文方式传输,其中最为重要且棘手的就是将要访问的域名,即 SNI(Server Name Indication)。同时还有用于告知客户端…

javaEE高阶---MyBatis

一 : 什么是MyBatis MyBatis是更简单完成程序和数据库交互的工具,也就是更简单的操作和读取数据库的工具.MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的动作 . MyBatis …

[oeasy]python0037_终端_terminal_电传打字机_tty_shell_控制台_console_发展历史

换行回车 回忆上次内容 换行 和 回车 是两回事 换行 对应字节0x0ALine-Feed 水平 不动垂直 向上喂纸 所以是 feed 回车 对应字节0x0DCarriage-Return 垂直 不动水平 回到纸张左侧 可移动的打印头 运输字符 的 装置 (Carriage)回到 行首 所以是 Return tty、terminal、shell、…

【视觉SLAM】DM-VIO: Delayed Marginalization Visual-Inertial Odometry

L. v. Stumberg and D. Cremers, “DM-VIO: Delayed Marginalization Visual-Inertial Odometry,” in IEEE Robotics and Automation Letters, vol. 7, no. 2, pp. 1408-1415, April 2022, doi: 10.1109/LRA.2021.3140129. 论文阅读方法:Title,Abstract…

百趣代谢组学文献分享:学科交叉研究,微生物回收重金属机制研究

发表期刊:Environment International 影响因子:7.297 发表时间:2019年 合作单位:福建农林大学 百趣代谢组学文献分享,该文章是BIOTREE协助客户2019年发表在Environment International上的关于微生物回收重金属机制研…