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

news2024/11/25 22:41:47

使用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.coloradmin.cn/o/1219560.html

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

相关文章

uniapp 手动调用form表单submit事件

背景&#xff1a; UI把提交的按钮弄成了图片&#xff0c;之前的button不能用了。 <button form-type"submit">搜索</button> 实现&#xff1a; html&#xff1a; 通过 this.$refs.fd 获取到form的vue对象。手动调用里面的_onSubmit()方法。 methods:…

掌握苏宁API,一键获取商品详情,解锁无尽商业可能

苏宁的API接口可以用于获取商品详情。以下是一个示例的API接口&#xff0c;通过商品ID获取商品详情&#xff1a; https://open.suning.com/api/content/product/getById?productId商品ID&appKey你的应用密钥&sign你的签名&formatjson 在上面的接口中&#xff0c…

无人智能货柜:引领便捷购物新体验

无人智能货柜&#xff1a;引领便捷购物新体验 无人智能货柜利用人工智能技术&#xff0c;将传统货架与电子商务相结合&#xff0c;形成智能销售终端。其采用先拿货后付款的购物模式&#xff0c;用户只需扫码、拿货、关门三个简洁流畅的步骤&#xff0c;极大地提升了消费者的购物…

文心一言 VS 讯飞星火 VS chatgpt (137)-- 算法导论11.3 3题

三、用go语言&#xff0c;考虑除法散列法的另一种版本&#xff0c;其中 h(k) k mod m&#xff0c;m 2 p − 1 2^p-1 2p−1&#xff0c;k为按基数 2 p 2^p 2p 表示的字符串。试证明:如果串可由串 y 通过其自身的字符置换排列导出&#xff0c;则x和y具有相同的散列值。给出一个…

Python基础入门---conda 如何管理依赖包以及复制相同环境的

文章目录 创建虚拟环境:创建虚拟环境并指定Python版本:安装依赖包:从环境导出依赖包清单:从依赖包清单创建环境:复制环境:移植环境:在Conda中,你可以使用conda create命令来创建和管理虚拟环境,而使用conda install命令来安装和管理依赖包。以下是一些基本的命令和步骤…

工业镜头中的远心镜头与普通镜头的光路

普通镜头&#xff1a; 主光线与镜头光轴有角度&#xff0c;工件上下移动时&#xff0c;像的大小有变化。 FOV&#xff1e;镜头前端直径。 物方远心镜头&#xff1a; 物方主光线平行于光轴&#xff0c;物距发生改变时&#xff0c;像高不会发生改变&#xff0c;测得的物体尺寸大…

技术实践|高斯集群服务器双缺省网关故障分析

导语&#xff1a;当前国产化数据库使用范围越来越广泛&#xff0c;在GaussDB数据库的使用过程中难免会遇到一些问题&#xff0c;有的问题是由于在安装过程中没有注意细节而产生的&#xff0c;多数隐患问题都是在特定场景下才会暴露出来&#xff0c;且暴露的时间未知&#xff0c…

MessageSourceUtil读取资源文件

在处理返回值提示的时候&#xff0c;需要根据local返回中文或者英文&#xff0c;因此要使用到国际化内容 操作 1&#xff0c;新建资源文件 在src/main/resources源文件夹下创建一个i18n的子目录&#xff0c; 然后创建中文和英文对应properties文件&#xff0c;然后输入自己的…

如何定位判断是前端的bug还是后端bug?

前言 随着开发软件趋向于大型化复杂化&#xff0c;软件测试逐渐成为一个专业&#xff0c;需要运用专门的方法和手段&#xff0c;需要专门人才来管理。但是外面的小道消息总是在传&#xff1a;软件测试就只是找bug的&#xff01;这个我可就不同意了~ 软件测试员是找bug&#x…

OceanMind海睿思数据中台迎来重磅更新,使用体验全面提升!

为了帮助客户拥有更好的产品使用体验&#xff0c;帮助实施数据治理项目降本增效&#xff0c;OceanMind海睿思的迭代更新从未止步。 OceanMind数据中台再度迎来重磅更新&#xff0c;该版本在大数据方面进行了规划设计&#xff0c;吸纳了30来自于项目的实际需求&#xff0c;更贴…

Linux友人帐之网络编程基础Samba服务器

一、概述 1.1Samba介绍 SMB协议 SMB(Server Message Block,服务信息块)协议是一个高层协议&#xff0c;它提供了在网络上的不同计算机之间共享文件、打印机和不同通信资料的手段。 SMB使用NetBIOS API3实现面向连接的协议&#xff0c;该协议为Vindows客户程序和服务提供了一个…

el-button 的:disabled不生效

添加:key&#xff0c;给个唯一值即可&#xff01;&#xff01;

骨传导耳机品牌排名前十,盘点最受欢迎的五款TOP级骨传导耳机

骨传导耳机品牌排名前十&#xff0c;最受欢迎的五款TOP级骨传导耳机是什么&#xff1f; 耳机市场上有很多品牌和型号的骨传导耳机&#xff0c;每个人对耳机的需求和使用场景也不尽相同。因此&#xff0c;在选择耳机时&#xff0c;确实不能盲目跟风或者仅仅看重品牌。为了帮助大…

视频修复软件 Aiseesoft Video Repair mac中文版功能

AIseesoft Video RepAIr mac是一款专业的视频修复软件&#xff0c;主要用于修复损坏或无法播放的视频文件。AIseesoft Video RepAIr是一个功能强大的程序,可以帮助恢复丢失或损坏的数据的视频。只要您以相同的格式提供示例视频,并在功能强大的技术的支持下,只需单击几下即可收获…

适用于4×4MiMo 4G/5G,支持GNSS和WiFi 6E的车载天线解决方案

德思特Panorama智能天线致力于为用户提供在各类复杂场景中稳定供给5G、WIFI和GNSS信号的卓越性能和支持。随着5G新频段逐渐应用、WIFI 6E频率升级以及多频定位应用的普及&#xff0c;传统的BAT[G]M-7-60[-24-58]系列天线已不再适用于当前多变的环境。 然而&#xff0c;BAT天线的…

一文带你了解ADC测试参数有哪些?

模数转换器&#xff08;ADC&#xff09;是数字电子系统中重要组成部分&#xff0c;用于捕获外部世界的模拟信号&#xff0c;如声音、图像、温度、压力等&#xff0c;并将它们转化为数字信号0\1, 以供计算机进行处理分析。ADC芯片在出厂交付之前&#xff0c;需要对产品的性能做各…

运维知识点-linux系统

linux 操作系统的目录结构和文件属性快捷键使用及文件系统分类对操作系统进行信息查询增删改查基础命令black Arch Linux Vmware 安装宝塔面板ssl初始化安装 查看默认入口和账号密码&#xff1a;腾讯云 专享版 渗透工具-白帽安全工程师Kaliubuntu 20.04 安装metasploitmsfvenom…

一文教会你SpringSecurity 自定义认证登录

目录 前言1-自定义用户对象2-自定义UserDetailsService3-自定义Authentication4-自定义AuthenticationProvider5-自定义AbstractAuthenticationProcessingFilter6-自定义认证成功和失败的处理类7-修改配置类8-测试 前言 现在登录方式越来越多&#xff0c;传统的账号密码登录已…

自动化测试,5个技巧轻松搞定

想要在质量保证团队中赢得核心&#xff1f;当你组建你的网络应用时要记住这些技巧&#xff0c;可以变得更容易分析并快速创建更多准确可重复的自动化测试。 1.歧义是敌人 尽可能使你的代码具体化。当然&#xff0c;你已经遵循了W3C标准&#xff0c;对吗&#xff1f;以下有三件…

中部高标准农田建设大会将于2024年8月在郑州召开

无农不稳、无粮则乱。农业保的是生命安全、生存安全&#xff0c;粮食安全是国家安全的重要基础。河南作为全国重要农业大省是国家重要粮食主产区&#xff0c;始终把粮食安全扛在肩上、抓在手上&#xff0c;把加快建设农业强省摆在重要位置。由振威国际会展集团等单位联合主办的…