nodejs项目开发过程:初始化、数据模块封装、功能模块封装

数据接口项目

1、需求分析

分角色操作不同的菜单

角色:系统管理员、业务管理员、会员

2、数据库建设

》》》写在前面的话

数据库部分往往是需求分析之后,在进行整体架构时确定数据实体、建设数据库

常见的数据分类:关系、专业术语、在数据库中关系表示二维表的意思

关系型数据库:以表的形式存储数据的数据库,经常用于常见的应用软件

---常见的:sqlite、access、mysql、mariadb、oracle、db2、sybase...

非关系型数据库:不以表的形式存储数据的数据库,经常用于大数据领域

--常见的:redis、mongodb...

关于数据库的使用:

  • 常见的图形化操作
  • 常见的操作语句(增删改查)     

创建数据库语句       create database 数据库名 default charset 'UTF8'

使用数据库语句 use 数据库名

创建数据库表语句    create table 表名(属性名 数据类型 是否非空 主键 描述)

添加测试数据 insert into 表名(各个属性名)values(第一组值),(第二组值),(第三组值)

查找语句 select 属性名 from 表名 where 条件

项目初始化

确定项目开发环境:Node js 环境、Express脚手架

创建数据接口项目:

-- 全局安装express项目脚手架
$ npm install express-generator -g

-- 通过express命令快速创建一个项目
$ express -e bz210701api

创建项目,安装依赖并启动项目

$ cd bz201701api
$ npm install 
$ npm start

初始化完成的浏览器页面 在页面地址栏输入localhost:3000

浏览器页面显示Expres证明初始化成功

封装数据库访问模块

将与数据库连接的代码部分进行封装

1、安装依赖

$  npm i mysql2 -S

2、创建数据模块

创建routes/db.js用于封装数据库链接信息,如下

/*
 * @Author: damu 1007821300@qq.com
 * @Date: 2022-06-01 11:42:31
 * @LastEditors: damu 1007821300@qq.com
 * @LastEditTime: 2022-06-01 11:48:29
 * @FilePath: \bz210701api\routes\db.js
 * @Description: 数据库访问模块
 * 
 * Copyright (c) 2022 by damu 1007821300@qq.com, All Rights Reserved. 
 */
const mysql = require('mysql2')

const { mysql_conf } = require('../config/global.json')

const pool = mysql.createPool({
  host: mysql_conf.host,
  user: mysql_conf.user,
  password: mysql_conf.password,
  database: mysql_conf.database,
  waitForConnections: mysql_conf.waitForConnections,
  connectionLimit: mysql_conf.connectionLimit,
  queueLimit: mysql_conf.queueLimit
});

module.exports = pool.promise();

3、全局配置

将和代码无关的配置信息,如数据库链接账号、密码等信息,单独抽取到一个配置文件中进行管理,提高操作的安全性。

创建全局配置文件:bz20107api/config/global.json,如下:

{
  "mysql_conf": {
    "host": "localhost",
    "port": 3306,
    "user": "root",
    "password": "root",
    "database": "bz21070601",
    "waitForConnections": true,
    "connectionLimit": 10,
    "queueLimit": 0
  }
}

数据业务模块

内容:操作数据库中数据的模块,将所有方法封装成对象,并共享出去

创建文件夹:services/,创建菜单业务模块:serivces/menus.service.js,如下:

/*
 * @Author: damu 1007821300@qq.com
 * @Date: 2022-06-01 14:45:43
 * @LastEditors: damu 1007821300@qq.com
 * @LastEditTime: 2022-06-01 15:01:40
 * @FilePath: \bz210701api\services\menus.service.js
 * @Description: 菜单业务模块
 * 
 * Copyright (c) 2022 by damu 1007821300@qq.com, All Rights Reserved. 
 */
const db = require('../routes/db')

class MenuService {
  /** 查询全部菜单 */
  async findAll(){
    const statement = `select id, title, icon, href, pid, tps, sts from menus`
    let [rows] = await db.query(statement)
    return rows
  }

  /** 分页查询菜单 */
  async findByPage(page=1, size=10) {
    const startId = (page - 1) * size
    const statement = `select id, title, icon, href, pid, tps, sts from menus limit ?, ?`
    let [rows] = await db.query(statement, [startId, size])
    return rows
  }

  /** 查询菜单总数 */
  async findTotal() {
    const statement = `select count(1) as cnt from menus`
    let [rows] = await db.query(statement)
    return rows
  }

  /** 根据名称查询菜单 */
  async findByTitle(title) {
    const statement = `select id, title, icon, href, pid, tps, sts from menus where title = ?`
    let [rows] = await db.query(statement, [title])
    return rows
  }

  /** 根据编号查询菜单 */
  async findById(id) {
    const statement = `select id, title, icon, href, pid, tps, sts from menus where id = ?`
    let [rows] = await db.query(statement, [id])
    return rows
  }

  /** 增加菜单 */
  async add(title, icon, href, pid, tps) {
    const statement = `insert into menus(title, icon, href, pid, tps)
                        values(?,?,?,?,?)`
    let [rows] = await db.query(statement, [title, icon, href, pid, tps])
  }

  /** 编辑菜单 */
  async edit(id, title, icon, href, pid, tps, sts) {
    const statement = `update menus set title = ?, icon = ?, 
                                    href= ?, pid = ?, tps = ?,
                                    sts = ? where id = ?`
    let [rows] = await db.query(statement, [title, icon, href, pid, tps, sts, id])
  }

  /** 删除菜单 */
  async delete(id) {
    const statement = `delete from menus where id = ?`
    return await db.query(statement, [id])
  }
}

module.exports = new MenuService()

// test
// const ms = new MenuService()
// ms.findByPage(1, 3).then(res => console.log(res))

路由模块

内容: 提供前端请求与后端数据操作的接口

1、构建模块

创建routes/menus.js路由模块,用于处理数据

/*
 * @Author: damu 1007821300@qq.com
 * @Date: 2022-06-01 16:07:15
 * @LastEditors: damu 1007821300@qq.com
 * @LastEditTime: 2022-06-01 16:54:16
 * @FilePath: \bz210701api\routes\menus.js
 * @Description: 菜单路由模块
 * 
 * Copyright (c) 2022 by damu 1007821300@qq.com, All Rights Reserved. 
 */
const express = require('express')

const router = express.Router()

const menuService = require('../services/menus.service')

/**
 * 查询菜单列表
 *    参数:q  1-查询全部  2-分页查询
 */
router.get('/list', async (req, res) => {
  // 解构数据
  let {q=1, page=1, size=10} = req.query
  let ret = []
  // 查询数据
  if(parseInt(q) === 1) {
    ret = await menuService.findAll()
  } else if(parseInt(q) === 2) {
    ret = await menuService.findByPage(page, size)
  }
  // 返回结果
  res.json({
    code: 200,
    msg: 'ok',
    data: ret
  })
})

/** 查询菜单总数 */
router.get('/total', async(req, res) => {
  let ret = await menuService.findTotal()
  res.json({
    code: 200,
    msg: 'success',
    data: ret
  })
})

/** 增加菜单数据 */
router.post('/add', async(req, res) => {
  // 请求体中解构数据
  let {title='', icon='', href='', pid=0, tps=0} = req.body
  // 数据逻辑验证
  if(title.trim() === '' || href.trim() === '') {
    res.json({
      code: 601,
      msg: '缺少关键参数',
      data: []
    })
    return
  }

  // 数据业务验证
  let ret = await menuService.findByTitle(title)
  if(ret.length > 0) {
    res.json({
      code: 602,
      msg: '该菜单名称已经存在',
      data: []
    })
    return 
  }

  // 添加数据
  let ret2 = await menuService.add(title, icon, href,pid, tps)
  console.log(ret2)
  if(ret2.insertId > 0) {
    res.json({
      code: 200,
      msg: 'ok',
      data: [{id: ret2.insertId, title, icon, href, pid, tps}]
    })
  } else {
    res.json({
      code: 700,
      msg: '系统繁忙,请稍后再试',
      data: []
    })
  }
  
})

/** 编辑菜单 */
router.put('/edit', async(req, res) => {
  // 解构数据
  let {id=-1, title='', icon='', href='', pid=0, tps=0, sts=0} = req.body
  // 数据校验
  if(id === -1 || title.trim() === '' || href.trim() === '') {
    res.json({
      code: 601,
      msg: '缺少关键参数',
      data: []
    })
    return
  }
  // 编辑数据
  let ret = await menuService.edit(id, title, icon, href, pid, tps, sts)
  if(ret.affectedRows > 0) {
      // 返回响应
      res.json({
        code: 200,
        msg: 'edit ok',
        data: [{id, title, icon, href, pid, tps, sts}]
      })
  } else {
    res.json({
      code: 700,
      msg: '系统繁忙,请稍后再试',
      data: []
    })
  }
  
})

/** 根据id删除菜单 */
router.delete('/del', async(req, res) => {
  // 1、解构数据
  let {id} = req.query
  // 2、删除数据
  await menuService.delete(id)
  // 3、返回结果
  res.json({
    code: 200,
    msg: 'delete ok',
    data: []
  })
})

module.exports = router

2、注册路由

....
var menusRouter = require('./routes/menus')
...

app.use('/menus', menusRouter)
....

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值