使用express连接MySQL数据库编写基础的增、删、改、查、分页等接口

使用express连接MySQL数据库编写基础的增、删、改、查、分页接口

安装express-generator生成器

cnpm install -g express-generator

通过生成器创建项目

express peifang-server

切换至serverAPI目录

cd peifang-server

下载所需依赖

cnpm install 

运行项目

npm start

访问项目:在浏览器地址栏输入127.0.0.1:3000

单方事故都发给

开始编写接口

1. 在项目中安装MySQL

cnpm install -S mysql
在这里插入图片描述

2. 在项目的根目录下新建config/index.js文件,用来存放数据库的相关配置信息

const sqlconfig = {
  host: 'localhost',  // 连接地址
  user: 'root',    //用户名
  password: 'root',  //密码
  port:  3306 ,   //端口号
  database: 'peifang'   //数据库名
}
module.exports = sqlconfig

3. 在项目的根目录下新建db/index.js文件夹,用来编写连接数据库的相关方法

const mysql = require('mysql')
const sqlconfig = require('../config/index.js')
const e = require("express");
/**
 * 连接数据库的两种简单方式:
 * 1. 使用mysql.createConnection连接数据库。
 * 2. 使用连接池 pool.createPool()。
 */

// 方式1 使用mysql.createConnection连接数据库
let mySql = (sql, data) => {
  return new Promise((resolve, reject) => {
    //连接数据库
    let conn = mysql.createConnection(sqlconfig)
    conn.query(sql, data, (err, result) => {
      console.log(err, result, '执行SQL语句');
      // 错误信息
      if (err) {
        // 当连接不再使用时,用conn对象的release方法将其归还到连接池中
        conn.release()
        reject(err);
      } else {
        resolve(result)
      }
    })
  })
}

// 方式2 使用连接池 pool.createPool()
let pool = mysql.createPool(sqlconfig)
// 封装执行数据库
pool.getConnection((err, conn) => {
  return new Promise((resolve, reject) => {
    if (err) {
      // 当连接不再使用时,用conn对象的release方法将其归还到连接池中
      conn.release()
      reject(err)
    } else {
      resolve(conn)
    }
  })
})

// 方式3 使用mysql.createConnection连接数据库并进行基础封装
const conn = mysql.createConnection(sqlconfig)
conn.connect(err => {
  if (err) {
    console.log("连接失败")
  } else {
    console.log("连接成功,当前连接线程ID"+conn.threadId);
  }
})
module.exports = {
  mySql,
  pool,
  conn,
}

4. 创建数据库及对应的数据表

  • part数据表(成分表)
    在这里插入图片描述
  • scheme数据表(配方表)
    在这里插入图片描述
  • scheme_detail数据表(配方详情表)
    在这里插入图片描述
  • history数据表(历史价格表)
    在这里插入图片描述

5. 设置数据表中创建时间字段自动填入

ALTER TABLE peifang.history MODIFY COLUMN `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间';
ALTER TABLE peifang.scheme MODIFY COLUMN `createTime` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间';
ALTER TABLE peifang.part MODIFY COLUMN `create_time` datetime NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间';

6. 在router目录下新建history.js、part.js、scheme.js、scheme_detail.js文件,并在app.js文件中进行相关路由引入,具体如下所示。

var partRouter = require('./routes/part');
var schemeRouter = require('./routes/scheme');
var schemeDetailRouter = require('./routes/scheme_detail');
var historyRouter = require('./routes/history');

app.use('/part', partRouter);
app.use('/scheme', schemeRouter);
app.use('/schemeDetail', schemeDetailRouter);
app.use('/history', historyRouter);

7. 编写数据表的单条数据新增、批量数据新增、删、单条数据修改、批量数据修改、全部查询、分页查询等接口

  1. 查询所有
router.get("/list", (req, res) => {
  const sql = "SELECT * FROM part";
  conn.query(sql,function(err,result){
    if(err){
      res.send({
        status: 400,
        msg: '查询语句执行异常'
      })
    }
    res.json({
      status: 200,
      msg: '查询成功',
      list: result
    })
  })
});
  1. 分页查询
router.get("/listByPage", (req, res) => {
  const size = Number(req.query.size)
  const page = Number(req.query.page)
  const start = (page - 1) * size;
  // 从第start开始取,一共取size个数据
  const sql = `SELECT * FROM part LIMIT ${start}, ${size}`;
  const countSql = 'SELECT count(id) as total FROM part'
  conn.query(sql, (err, data) => {
    if(err){
      res.send({
        status: 400,
        msg: '查询语句执行异常'
      })
    }
    conn.query(countSql, (error, count) => {
      if(err){
        res.send({
          status: 400,
          msg: '查询语句执行异常'
        })
      }
      console.log(count, 'count')
      res.json({
        status: 200,
        msg: '查询成功',
        list: data,
        total: count[0].total
      })
    })
  })
})

  1. 根据id查询详情
router.get("/partInfo/:id", (req, res) => {
  const id = String(req.params.id)
  const sql = `SELECT * FROM part WHERE id = '${id}'`
  conn.query(sql, (error, data) => {
    if (error) {
      res.json({
        status: 404,
        msg: err.message
      });
    } else {
      res.json({
        status: 200,
        msg: '查询成功',
        list: data
      })
    }
  })
})
  1. 新增
router.post("/addPart", (req, res) => {
  const { name , price, MJProportion, proteinProportion, calciumProportion, phosphorusProportion} = req.body
  const querySql = `SELECT * FROM part WHERE name = '${name}'`
  conn.query(querySql, (err, data) => {
    console.log(err, data)
    if (data.length > 0) {
      res.send({
        status: 400,
        msg: '当前成分已存在!'
      })
    } else {
      // 构建sql语句
      const sql = 'INSERT INTO part set ?'
      const params = {
        name: name,
        price: price,
        mj_proportion: MJProportion,
        protein_proportion: proteinProportion,
        calcium_proportion: calciumProportion,
        phosphorus_proportion: phosphorusProportion
      }
      // 执行sql语句
      conn.query(sql, params, (err1, data1) => {
        // 判断sql是否执行失败
        if (err1) {
          res.send({
            status: 400,
            msg: err1.message
          })
        } else if (data1.affectedRows !== 1){
          // 判断数据是否插入成功 看affectedRows的值是否为1,不为1则写入失败
          res.send({
            status: 400,
            msg: '数据写入失败'
          })
        } else {
          // 否则写入成功 返回客户端
          res.send({
            status: 200,
            msg: '新增成功'
          })
        }
      })
    }
  })
})
  1. 删除
router.delete("/deletePartById/:id", (req, res) => {
  const id = String(req.params.id)
  const sql = `delete from part where id = '${id}'`
  conn.query(sql, (err, data) => {
    if (err) {
      res.send({
        status: 400,
        msg: '查询语句执行异常'
      })
    } else if (data.affectedRows !== 1) {
      // affectedRows不为1则执行失败
      res.send({
        status: 400,
        msg: '数据删除失败'
      })
    } else {
      res.json({
        status: 200,
        msg: '数据删除成功',
      })
    }
  })
})
  1. 修改
router.put("/updatePart/:id", (req, res) => {
  const id = String(req.params.id)
  const { price, MJProportion, proteinProportion, calciumProportion, phosphorusProportion } = req.body
  const params = {
    price: price,
    mj_proportion: MJProportion,
    protein_proportion: proteinProportion,
    calcium_proportion: calciumProportion,
    phosphorus_proportion: phosphorusProportion,
  }
  // 方法一:
  // const sql = 'update user set ? where id = ?'
  // db.query(sql, [params, id], (err, data) => {
  
  // 方法二:
  const sql = `update part set ? where id = '${id}'`
  conn.query(sql, params, (err,  data) => {
    if (err) {
      res.send({
        status: 400,
        msg: err.message
      })
    } else if (data.affectedRows !== 1){
      res.send({
        status: 400,
        msg: '修改失败!'
      })
    } else {
      res.json({
        status: 200,
        msg: '修改成功!'
      })
    }
  })
})
module.exports = router;
  1. 批量插入
router.post("/addScheme",(req,res) => {
  const {name, description, list} = req.body
  const sql = `select * from scheme where name = '${name}'`
  pool.query(sql, (err, result) => {
    if (err) {
      res.send({
        status: 400,
        msg: err.message
      })
    } else if (result.length > 0) {
      res.json({
        status: 400,
        msg: '当前配方已存在!',
        data: result
      })
    } else {
      const insertSql = `INSERT INTO scheme set ?`
      pool.query(insertSql, {name, description}, (err1, result1) => {
        if (err1) {
          res.json({
            status: 404,
            msg: err.message
          });
        } else if (result1.affectedRows !== 1){
          res.send({
            status: 400,
            msg: '数据写入失败'
          })
        } else {
          // 批量插入
          const insertSQL = "INSERT INTO scheme_detail(scheme_id, part_id, part_weight, part_price) VALUES ?"
          const schemeList = []
          list.forEach(item => {
            schemeList.push([
              result1.insertId,
              item.part_id,
              item.part_weight,
              item.part_price,
            ])
          })
          pool.query(insertSQL, [schemeList], (err2, data2) => {
            if (err2) {
              res.json({
                status: 404,
                msg: err2.message
              });
            }
            res.json({
              status: 200,
              msg: '新增成功!',
              data: data2
            })
          })
        }
      })
    }
  })
})
  1. 批量更新
router.put("/updateScheme/:id", (req, res) => {
  const id = String(req.params.id)
  const {name, description, list} = req.body
  const sql = `update scheme set ? where id = '${id}'`
  pool.query(sql, { name, description }, (err, data) => {
    if (err) {
      res.send({
        status: 400,
        msg: err.message
      })
    } else if (data.affectedRows !== 1){
      res.send({
        status: 400,
        msg: '修改失败!'
      })
    } else {
      // 批量更新方案一:循环数据逐条进行更新或插入
      // 批量更新方案二:将原有的数据全部清除,再重新全部插入
      // 批量更新方案三:通过SQL直接修改
      const insertSQL = "replace into scheme_detail (id, scheme_id, part_id, part_weight, part_price) values ?;"
      const insertSQL1 = "INSERT INTO scheme_detail (id, scheme_id, part_id, part_weight, part_price) VALUES ? " +
        "ON DUPLICATE KEY UPDATE id=values(id),scheme_id=values(scheme_id),part_weight=values(part_weight),part_price=values(part_price);"
      const schemeList = []
      list.forEach(item => {
        schemeList.push([
          item.id,
          id,
          item.part_id,
          item.part_weight,
          item.part_price,
        ])
      })
      pool.query(insertSQL1, [schemeList], (err2, data2) => {
        if (err2) {
          res.json({
            status: 404,
            msg: err2.message
          });
        }
        res.json({
          status: 200,
          msg: '修改成功!',
          data: data2
        })
      })
    }
  })
})

项目源码地址

参考地址

参考地址1

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

echarts 实现同一组legend控制两个饼图示例

实现同一组legend控制两个饼图示例: 该示例有如下几个特点: ①饼图不同值实现分割 ②实现tooltip自定义样式(echarts 实现tooltip提示框样式自定义-CSDN博客) ③自定义label内容 ④不同值颜色渐变 代码如下: this.o…

CentOS挂载:解锁文件系统的力量

目录 引言1 挂载简介2 挂载本地分区3 挂载网络共享文件系统4 使用CIFS挂载结论 引言 在CentOS(一种基于Linux的操作系统)上挂载文件系统是一项常见而重要的任务,无论是将新的磁盘驱动器添加到系统,还是挂载网络共享资源&#xff…

一个iOS tableView 滚动标题联动效果的实现

效果图 情景 tableview 是从屏幕顶部开始的,现在有导航栏,和栏目标题视图将tableView的顶部覆盖了 分析 我们为了达到滚动到某个分区选中标题的效果,就得知道 展示最顶部的cell或者区头在哪个分区范围内 所以我们必须首先获取顶部的位置 …

【bigo前端】egret中的对象池浅谈

本文首发于:https://github.com/bigo-frontend/blog/ 欢迎关注、转载。 egret是一款小游戏开发引擎,支持跨平台开发,之前使用这款引擎开发了一款捕鱼游戏,在这里简单聊下再egret中关于对象池的使用,虽然该引擎已经停止…

第六十二周周报

学习目标: 一、实验 二、论文 学习时间: 2023.11.11-2023.11.17 学习产出: 实验 1、CB模块实验效果出来了,加上去效果不太行,后续实验考虑是否将CB模块换到其他地方 2、CiFAR100实验已完成,效果比Vi…

大模型之十二十-中英双语开源大语言模型选型

从ChatGPT火爆出圈到现在纷纷开源的大语言模型,众多出入门的学习者以及跃跃欲试的公司不得不面临的是开源大语言模型的选型问题。 基于开源商业许可的开源大语言模型可以极大的节省成本和加速业务迭代。 当前(2023年11月17日)开源的大语言模型如下&#…

基于DE10-Standard Cyclone V SoC FPGA学习---开发板简介

基于DE10-Standard Cyclone V SoC FPGA学习---开发板简介 简介产品规格基于 ARM 的 HPS配置与调试存储器件通讯连接头显示器音频视频输入模数转换器开关、按钮、指示器传感器电源 DE10-Standard 开发板系统框图Connect HTG 组件配置设计资源其他资源 简介 开发板资料 见 DE10-…

什么是CRM管理系统

什么是CRM管理系统 市场竞争的日益激烈,企业对于客户关系的重视程度不断提升。为了更好地管理和维护客户关系,很多企业开始引入CRM(Customer Relationship Management)管理系统。那么,什么是CRM管理系统呢&#xff1f…

Jenkins代码检测和本地静态检查

1:Jenkins简介 Jenkins是一个用Java编写的开源的持续集成工具;Jenkins自动化部署可以解决集成、测试、部署等重复性的工作,工具集成的效率明显高于人工操作;并且持续集成可以更早的获取代码变更的信息,从而更早的进入测…

Java 之拼图小游戏

声明 此项目为java基础的阶段项目,此项目涉及了基础语法,面向对象等知识,具体像语法基础如判断,循环,数组,字符串,集合等…; 面向对象如封装,继承,多态,抽象类,接口,内部类等等…都有涉及。此项目涉及的内容比较多,作为初学者可以很好的将前面的知识串起来。此项目拿来练手以及…

golang学习笔记——基础01

文章目录 golang概述Go 语言特色Go 语言用途 Go 语言结构执行 Go 程序 Go 语言包管理01Go 语言包管理02Go 语言基础语法Go 标记行分隔符注释标识符字符串连接关键字、预定义标识符Go 语言的空格格式化字符串 Go 语言数据类型数字类型浮点型其他数字类型 Go 语言变量变量声明零值…

Linux下安装部署redis(离线模式)

一、准备工作 1.下载redis的安装包 下载地址:Index of /releases/ 大家可以自行选择redis的版本,笔者选择的是最新的 2.上传到服务器 前提是我先在服务器上创建了一个目录redis7.2.3,我直接上传到这个目录下 二、安装redis 1.解压redis t…

03-瑞吉外卖关于菜品/套餐分类表的增删改查

新增菜品/套餐分类 页面原型 当我们在后台系统中添加菜品/套餐时,需要选择一个菜品/套餐分类,在移动端也会按照菜品分类和套餐分类来展示对应的菜品和套餐 第一步: 用户点击确定按钮执行submitForm函数发送Ajax请求,将新增菜品/套餐表单中输入的数据以json形式提交给服务端,…

代码随想录算法训练营第24天|77. 组合

JAVA代码编写 77. 组合 给定两个整数 n 和 k,返回范围 [1, n] 中所有可能的 k 个数的组合。 你可以按 任何顺序 返回答案。 示例 1: 输入:n 4, k 2 输出: [[2,4],[3,4],[2,3],[1,2],[1,3],[1,4], ]示例 2: 输入…

IIC协议保姆级教学

目录 1.IIC协议概述 2.IIC总线传输 3.IIC-51单片机应用 1.起始信号 2.终止信号 3.应答信号 4.数据发送 4.IIC-32单片机应用 用到的库函数: 1.IIC协议概述 IIC全称Inter-Integrated Circuit (集成电路总线)是由PHILIPS公司在80年代开发的两线式串行总线&am…

hive sql 取当周周一 str_to_date(DATE_FORMAT(biz_date, ‘%Y%v‘), ‘%Y%v‘)

select str_to_date(DATE_FORMAT(biz_date, %Y%v), %Y%v)方法拆解 select DATE_FORMAT(now(), %Y%v), str_to_date(202346, %Y%v)

和鲸科技创始人范向伟受邀出席“凌云出海,来中东吧”2023华为云上海路演活动

11月9日,华为云“凌云出海,来中东吧”系列路演活动第二场在上海正式开启。聚焦“创业全球化”,本次活动由华为云携手阿布扎比投资办公室(ADIO)举办,旨在与渴望出海发展的优秀创业者们共探出海中东新商机。 …

qt 重载信号,使用““方式进行connect()调用解决方案

问题 在Qt中,重载的信号默认是无法使用&这种方式调用的。 因为&只能绑定到一个具体的信号,而重载的信号名称相同,编译器无法确定要绑定哪一个信号。 解决方案 如果非要使用&绑定重载的信号,可以使用函数指针进行转…

元宇宙3D云展厅应用到汽车销售的方案及特点

为了紧紧抓住年轻消费者的需求,汽车销售行业也正在经历一场深刻的变革。在这个变革的前沿,元宇宙3D汽车展厅作为一项全新技术闪亮登场,打破了传统汽车销售模式的限制,为消费者带来了前所未有的购车体验。 元宇宙3D汽车展厅采用了尖…

基于java web的中小型人力资源管理系统

末尾获取源码 开发语言:Java Java开发工具:JDK1.8 后端框架:SSM 前端:Vue 数据库:MySQL5.7和Navicat管理工具结合 服务器:Tomcat8.5 开发软件:IDEA / Eclipse 是否Maven项目:是 目录…
最新文章