Node的学习以及学习通过Node书写接口并简单操作数据库

Node的学习

  • Node的基础
  • 上述是关于Node的一些基础,总结的还行;

利用Node书写接口并操作数据库

1. 初始化项目

  • 创建新的项目文件夹,并初始化 package.json
mkdir my-backend
cd my-backend
npm init -y

2. 安装必要的依赖

  • 安装Express.js(用于处理http请求)
npm install express
  • 安装CORS,支持跨域请求
npm install cors
  • 安装nodemon,使用开发模式(自动重启服务); s
npm install --save-dev nodemon

3. 创建主程序文件index.js

  • 目前是绝大多数逻辑都写在了主程序文件index.js中,后续会将里面绝大部分内容抽离开来,比如路由信息、中间件、控制器等;
const db = require('./db'); // 有几个常用的操作路径的方式需要注意;// 引入必要模块
const express = require('express');
const cors = require('cors');const app = express(); // 创建 Express 应用实例
const PORT = 3000; // 设置服务端口// 中间件配置
app.use(cors()); // 允许跨域
app.use(express.json()); // 解析 JSON 格式的请求体
app.use(express.urlencoded({ extended: true })); // 解析 URL 编码的请求体// 路由
app.get('/', (req, res) => {res.send('Hello, World! Welcome to the Node.js backend!');
});app.post('/data', (req, res) => {const { name, age } = req.body; // 从请求体中获取数据res.json({ message: `Received data for ${name}, age ${age}` });
});/***  扩展功能:1. 增加更多路由;或者说查询路由*/
app.get('/users', (req, res) => {db.query('SELECT * FROM users', (err, results) => {if (err) {res.status(500).json({ error: 'Database query failed' });return;}res.json(results);});
});// 2. 插入用户数据
app.post('/addUser', (req, res) => {// const { id, username, password } = req.body;db.query('INSERT INTO users (id, username, password) VALUES (?, ?, ?)', [id, username, password], (err, result) => {if (err) {res.status(500).json({ error: 'Failed to insert user' });return;}res.json({ message: 'User created successfully', userId: result.insertId });});
})// post请求一般都会解析用户数据;
app.post('/users', (req, res) => {const { name } = req.body;res.json({ message: `User ${name} created successfully!` });
});// 启动服务
app.listen(PORT, () => {console.log(`Server is running on http://localhost:${PORT}`);
});

4. 主程序中连接数据库操作

  • 安装数据库
npm install mongoose    # MongoDB
npm install mysql2      # MySQL
  • 连接数据库 db.js
const mysql = require('mysql2');// 创建数据库连接
const db = mysql.createConnection({host: 'localhost',user: 'root',password: '123456',database: 'my_db_01'
});// 连接数据库
db.connect((err) => {if (err) {console.error('Error connecting to the database:', err);return;}console.log('Connected to MySQL database.');
});module.exports = db; // 导出数据库连接实例

5. 运行服务器

npx nodemon index.js
  • 结果图
    表示成功连接上数据库

6. 测试

get接口方法测试
  • 在浏览器测试; 输入:http://localhost:3000/users
    在这里插入图片描述
  • postman测试
    postman测试结果图
post接口方法测试

在这里插入图片描述

  • 在发送请求以后,即可在数据库中查看到新添加的数据新添加的数据

Node项目的规范化

  • 上面的Node项目已经可以完成一个较为试水的项目了,但是项目结构需要优化下:
    Node项目规范化结构

路由模块写法

  • 将原先写在app.js(index.js)中的路由信息分开写,分为users.js和students.js
  • 以users.js为例,其路由信息的js书写如下:
// 用户路由
const express = require('express'); 
const router = express.Router(); 
const db = require('../db');  // 引入数据库配置信息// 获取所有用户数据
router.get('/users', (req, res) => {db.query('SELECT * FROM users', (err, results) => {if (err) {res.status(500).json({ error: 'Database query failed' });return;}res.json(results);});});// 添加用户信息
router.post('/addUser', (req, res) => {const { id, username, password } = req.body;db.query('INSERT INTO users (id, username, password) VALUES (?, ?, ?)', [id, username, password], (err, result) => {if (err) {res.status(500).json({ error: 'Failed to insert user' });return;}res.json({ message: 'User created successfully', userId: result.insertId });});})module.exports = router; 
  • 添加到app.js的路由书写如下:
// app.js 作为入口文件;const express = require('express');
const cors = require('cors');
const userRoutes = require('./routes/users'); // 引入用户路由
const studentsRoutes = require('./routes/students'); // 引入学生路由const app = express(); 
const PORT = 3000; // 中间件配置
app.use(cors()); // 允许跨域
app.use(express.json()); // 处理JSON格式
app.use(express.urlencoded({ extended: true })); // 处理URL编码// 基础路由
app.get('/', (req, res) => {res.send('Hello, World! Welcome to the Node.js backend!');
});// 使用路由模块
app.use('/api', userRoutes); // 将用户相关路由挂载到/api中;
app.use('/api', studentsRoutes); // 启动服务
app.listen(PORT, () => {console.log(`Server is running on http://localhost:${PORT}`);
});
  • 问题:为什么使用路由模块需要将用户相关路由挂载到 /apo中,而不是直接/ 呢
    • RESTful风格标准(现代web开发的一种标准)
    • 防止命名冲突,如果项目中没有统一前缀,路由很容易与其他资源冲突
    • 前端调用时的统一管理,有利于集中管理API

控制器写法

  • 其实控制器就是在路由的基础上进一步优化,这一点非常关键;
  • 具体见操作数据库的代码

路径参数和查询参数的比较

  • 路径参数查询参数 是两种不同的传参方式,需要在路由定义和请求中保持一致。

路径参数

  • 路径参数:通过id查询
router.get('/getStudentsById/:id', getStudentById);
  • Postman 请求示例
GET http://localhost:3000/api/getStudentsById/101
const getStudentById = (req, res) => {console.log('req.params', req.params); const { id } = req.params; // 从路径参数中获取 idconsole.log('我已经获取到了id是', id);db.query('SELECT * FROM student WHERE id = ?', [id], (err, results) => {if (err) {res.status(500).json({ error: 'Database query failed' });return;}if (results.length === 0) {return res.status(404).json({ message: 'Student not found' });}res.json(results[0]);});
};

查询参数

  • 如果想通过 ?id=101 这样的查询参数传值,那么需要修改控制器中的代码,从 req.query 中获取参数。
  • 路由定义:
router.get('/getStudentsById', getStudentById); // 无需路径参数
  • Postman 请求示例:
GET http://localhost:3000/api/getStudentsById?id=101
  • 控制器代码修改:
const getStudentById = (req, res) => {console.log('req.query', req.query); const { id } = req.query; // 从查询参数中获取 idconsole.log('我已经获取到了id是', id);if (!id) {return res.status(400).json({ error: 'Student ID is required' });}db.query('SELECT * FROM student WHERE id = ?', [id], (err, results) => {if (err) {res.status(500).json({ error: 'Database query failed' });return;}if (results.length === 0) {return res.status(404).json({ message: 'Student not found' });}res.json(results[0]);});
};

两种方式的总结

  1. 路径参数(推荐):

    • URL 格式:/getStudentsById/:id
    • 请求示例:GET /api/getStudentsById/101
    • 后端通过 req.params 获取参数。
  2. 查询参数

    • URL 格式:/getStudentsById?id=101
    • 请求示例:GET /api/getStudentsById?id=101
    • 后端通过 req.query 获取参数

总结:使用 路径参数 更符合 RESTful 风格,代码更语义化。

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

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

相关文章

计算机视觉中的特征提取算法

摘要: 本文聚焦于计算机视觉中的特征提取算法,深入探讨尺度不变特征变换(SIFT)算法。详细阐述 SIFT 算法的原理,包括尺度空间构建、关键点检测、方向分配与特征描述子生成等核心步骤。通过 C#、Python 和 C 三种编程语…

java版询价采购系统 招投标询价竞标投标系统 招投标公告系统源码

功能描述 1、门户管理:所有用户可在门户页面查看所有的公告信息及相关的通知信息。主要板块包含:招标公告、非招标公告、系统通知、政策法规。 2、立项管理:企业用户可对需要采购的项目进行立项申请,并提交审批,查看所…

景联文科技入选中国信通院发布的“人工智能数据标注产业图谱”

近日,由中国信息通信研究院、中国人工智能产业发展联盟牵头,联合中国电信集团、沈阳市数据局、保定高新区等70多家单位编制完成并发布《人工智能数据标注产业图谱》。景联文科技作为人工智能产业关键环节的代表企业,入选图谱中技术服务板块。…

【小沐学GIS】基于C++绘制三维数字地球Earth(OpenGL、glfw、glut、QT)第三期

🍺三维数字地球系列相关文章如下🍺:1【小沐学GIS】基于C绘制三维数字地球Earth(456:OpenGL、glfw、glut)第一期2【小沐学GIS】基于C绘制三维数字地球Earth(456:OpenGL、glfw、glut)第二期3【小沐…

实景视频与模型叠加融合?

[视频GIS系列]无人机视频与与实景模型进行实时融合_无人机视频融合-CSDN博客文章浏览阅读1.5k次,点赞28次,收藏14次。将无人机视频与实景模型进行实时融合是一个涉及多个技术领域的复杂过程,主要包括无人机视频采集、实景模型构建、视频与模型…

MySQL通过binlog日志进行数据恢复

记录一次阿里云MySQL通过binlog日志进行数据回滚 问题描述由于阿里云远程mysql没有做安全策略 所以服务器被别人远程攻击把数据库给删除,通过查看binlog日志可以看到进行了drop操作,下面将演示通过binlog日志进行数据回滚操作。 1、查询是否开始binlog …

IDEA 修改格式化仅格式化本次改动代码

最近总是发现格式化的时候会格式化文件所有代码,提交Git 后再看提交日志,就很不清晰。修改方式如下 中文: 格式化代码快捷键[中文配置]: 英文: 格式化代码快捷键[英文配置]:

【含开题报告+文档+PPT+源码】基于微信小程序的点餐系统的设计与实现

开题报告 随着互联网技术的日益成熟和消费者生活水平与需求层次的显著提升,外卖点餐平台在中国市场上迅速兴起并深深植根于民众日常生活的各个角落。这类平台的核心在于构建了一个基于互联网的强大订餐服务系统,它无缝整合了餐饮商户资源与广大消费者的…

解决 MyBatis 中空字符串与数字比较引发的条件判断错误

问题复现 假设你在 MyBatis 的 XML 配置中使用了如下代码&#xff1a; <if test"isCollect ! null"><choose><when test"isCollect 1">AND exists(select 1 from file_table imgfile2 where task.IMAGE_SEQimgfile2.IMAGE_SEQ and im…

SpringBoot 手动实现动态切换数据源 DynamicSource (中)

大家好&#xff0c;我是此林。 SpringBoot 手动实现动态切换数据源 DynamicSource &#xff08;上&#xff09;-CSDN博客 在上一篇博客中&#xff0c;我带大家手动实现了一个简易版的数据源切换实现&#xff0c;方便大家理解数据源切换的原理。今天我们来介绍一个开源的数据源…

前端学习一

一 进程与线程 线程是进程执行的最小单位&#xff0c;进程是系统分配任务的最小单位。 一个进程可执行最少一个线程。线程分为子线程和主线程。 主线程关闭则子线程关闭。 二 浏览器进程 浏览器是多进程多线程应用。 进程包括&#xff1a; 浏览器进程 负责程序交互渲染…

EasyExcel 动态设置表格的背景颜色和排列

项目中使用EasyExcel把数据以excel格式导出&#xff0c;其中设置某一行、某一列单元格的背景颜色、排列方式十分常用&#xff0c;记录下来方便以后查阅。 1. 导入maven依赖&#xff1a; <dependency><groupId>com.alibaba</groupId><artifactId>easy…

概率论得学习和整理23:EXCEL 数据透视表基础操作

目录 1 选择数据&#xff0c;插入数据透视表 2 选择数据透视表生成位置 3 出现了数据透视表的面板 4 数据透视表的基本结构认识 4.1 交叉表/列联表 4.2 row, column, cell 一个新增的筛选器&#xff0c;就这么简单 4.3 可以只添加 rowcell/值 &#xff0c;也可以colu…

计算机网络从诞生之初到至今的发展历程

前言 "上网"&#xff0c;相信大家对这个动词已经不再陌生&#xff0c;网 通常指的是网络&#xff1b;在 2024 年的今天&#xff0c;网络已经渗透到了每个人的生活中&#xff0c;成为其不可或缺的一部分&#xff1b;你此时此刻在看到我的博客&#xff0c;就是通过网络…

GB28181系列三:GB28181流媒体服务器ZLMediaKit

我的音视频/流媒体开源项目(github) GB28181系列目录 目录 一、ZLMediaKit介绍 二、 ZLMediaKit安装、运行(Ubuntu) 1、安装 2、运行 3、配置 三、ZLMediaKit使用 一、ZLMediaKit介绍 ZLMediaKit是一个基于C11的高性能运营级流媒体服务框架&#xff0c;项目地址&#xf…

iPhone恢复技巧:如何从 iPhone 恢复丢失的照片

在计算机时代&#xff0c;我们依靠手机来捕捉和存储珍贵的回忆。但是&#xff0c;如果您不小心删除或丢失了手机上的照片怎么办&#xff1f;这真的很令人沮丧和烦恼&#xff0c;不是吗&#xff1f;好吧&#xff0c;如果您在 iPhone 上丢失了照片&#xff0c;您不必担心&#xf…

如何将你的 Ruby 应用程序从 OpenSearch 迁移到 Elasticsearch

作者&#xff1a;来自 Elastic Fernando Briano 将 Ruby 代码库从 OpenSearch 客户端迁移到 Elasticsearch 客户端的指南。 OpenSearch Ruby 客户端是从 7.x 版 Elasticsearch Ruby 客户端分叉而来的&#xff0c;因此代码库相对相似。这意味着当将 Ruby 代码库从 OpenSearch 迁…

Day8 神经网络中的导数基础

Day8 神经网络中的导数基础 导数的定义 导数&#xff08;Derivative&#xff09;是微积分中的一个核心概念&#xff0c;用于描述函数在某一点的变化率。简单来说&#xff0c;导数就是函数值随自变量微小变化而产生的变化量&#xff0c;即斜率或变化率。假设有一个函数 f ( x…

【视频生成模型】——Hunyuan-video 论文及代码讲解和实操

&#x1f52e;混元文生视频官网 | &#x1f31f;Github代码仓库 | &#x1f3ac; Demo 体验 | &#x1f4dd;技术报告 | &#x1f60d;Hugging Face 文章目录 论文详解基础介绍数据预处理 &#xff08;Data Pre-processing&#xff09;数据过滤 (Data Filtering)数据标注 (Data…

52 基于单片机的超声波、温湿度、光照检测分阶段报警

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 1.通过DHT11模块读取环境温度和湿度: 2.将湿度、障碍物距显示在lcd1602上面&#xff0c;第一行显示温度和湿度,格式为:xxCyy%&#xff0c;第二行显示超声波传感器测得的距离&#xff0c;格式为:Di…