Node实现简单的增删改查

1,676 阅读4分钟

一、简介

在做自己项目的时候,想获取数据就需要自己提供接口,用node是个不错的选择。

二、步骤

1. 初始化项目
npm init egg --type=simple

image.png

1⃣️ controller

用来接受用户传递过来的参数, 并对数据进行操作,在返回给用户

2⃣️ middleware

中间层, 可以在对应接口设置中间处理, 比如说token校验

3⃣️ service

用于对数据库进行操作, 增删改查

4⃣️ view

用于ejs渲染模版页面

5⃣️ router

用于路由的设置

2. 建立数据库表

新建数据库test并配置对应表

image.png

username: 用户名 password: 密码 signature: 签名 avatar: 头像 ctime: 创建时间

下载egg-mysql

npm i egg-mysql

在config目录下进行配置

这里我就用本地数据库了

image.png

config.default.js

 // 在配置数据库设置之前配置白名单,否则请求接口会出现csrf的报错
  config.security = {
    csrf: {
      enable: false,
      ignoreJSON: true
    },
    domainWhiteList: [ '*' ], // 配置白名单
  };  


 // 单数据库信息配置
exports.mysql = {
    client: {
      // host
      host: '127.0.0.1',
      // 端口号
      port: '3306',
      // 用户名
      user: 'root',
      // 密码
      password: '123456', // 初始化密码,没设置的可以不写
      // 数据库名
      database: 'test', // 我们新建的数据库名称
    },
    // 是否加载到 app 上,默认开启
    app: true,
    // 是否加载到 agent 上,默认关闭
    agent: false,
  };

plugin.js

  mysql: {
    enable: true,
    package: 'egg-mysql'
  }
3. 注册用户

1⃣️ 在service新建user.js

定义获取用户名函数

 async getUserByName(username) {
        const { app } = this
        try {
            // get代表查询, 第一个参数为查询的表, 第二个参数为根据哪个字段进行查询
            const result = app.mysql.get('user', { username })
            return result
        }catch(error) {
            console.log(error)
            return null
        }
    }

定义注册函数

    async register(params) {
        const { app } = this
        try {
            // insert 代表插入,  第一个参数为插入的表,第二个参数为插入的参数
            const result = await app.mysql.insert('user', params)
            return result
        }catch(error) {
            console.log(error)
            return null
        }
    }

2⃣️ 在controller层新建user.js

下载moment, 用于时间处理

npm i moment

定义注册函数

  const Controller = require('egg').Controller;
  const moment = require('moment')
  class UserController extends Controller {
  async register() {
        const { ctx } = this
        const { username, password, avatar, signature } = ctx.request.body; // 获取注册需要的参数
        if(!username || !password) {
            ctx.body = {
                code: 500,
                msg: '账号密码不能为空',
                data: null
            }
            return
        }
        // 从数据库中查对应用户
        const userInfo = await ctx.service.user.getUserByName(username)
        // 判断是否存在
        if(userInfo && userInfo.id) {
            ctx.body = {
                code: 500,
                msg: '用户名已被注册, 请重新输入',
                data: null
            }
            return
        }
        // 创建时间 
        const ctime = moment().format("YYYY-MM-DD HH:mm:ss")
        // 调用service层注册函数, 操作数据库 
        const result = await ctx.service.user.register({
            username,
            password,
            signature,
            avatar,
            ctime
          });
          
          if (result) {
            ctx.body = {
              code: 200,
              msg: '注册成功',
              data: null
            }
          } else {
            ctx.body = {
              code: 500,
              msg: '注册失败',
              data: null
            }
          }
    }
    }

3⃣️ 在router.js中定义路由

module.exports = app => {
    router.post('/api/user/register', controller.user.register) // 注册接口
    router.get('/api/user/getUserinfo', controller.user.getUserInfo) // 获取用户信息接口
}

4⃣️ 调试接口

image.png

image.png

4.登录

1⃣️ 下载egg-jwt 用于登录校验

npm i egg-jwt

2⃣️ 在config文件夹中进行配置

config.default.js

  config.jwt = {
    secret: 'test' // 相当于密匙
  }

plugin.js

  jwt: {
    enable: true,
    package: 'egg-jwt'
  }

3⃣️ 在controller目录下user.js新增登录函数

 async login() {
        const { ctx, app } = this
        const { username, password } = ctx.request.body
        const userInfo = await ctx.service.user.getUserByName(username)
        // 说明没有找到该用户
        if(!userInfo || !userInfo.id) {
            ctx.body = {
                code: 500,
                msg: '账号不存在',
                data: null
            }
            return
        }
        // 找到用户, 判断输入密码和数据库中密码是否相同
        if(userInfo && userInfo.password !== password) {
            ctx.body = {
                code: 500,
                msg: '密码错误',
                data: null
            }
            return
        }
        // 生成token
        const token = app.jwt.sign({
            id: userInfo.id,
            username: userInfo.username,
            // 失效时间
            exp: Math.floor(Date.now() / 1000) + (24 * 60 * 60) // token有效期为24小时
        }, app.config.jwt.secret)
        ctx.body = {
            code: 200,
            message: '登录成功',
            data: {
                token
            }
        }
    }

image.png

5. 设置中间件

1⃣️ 在middleware创建index.js

module.exports = (secret) => {
    return async function jwtErr(ctx, next) {
        // token会放到请求头上
        const token = ctx.request.header.authorization
        let decode
        if(token !== 'null' && token) {
            try {
                // 验证token
                decode = ctx.app.jwt.verify(token, secret)
                await next()
            }catch(error) {
                console.log(`error`, error)
                ctx.status = 200
                ctx.body = {
                    code: 401,
                    msg: 'token已过期, 请重新登录'
                }
                return
            }
        }else {
            ctx.status = 200
            ctx.body = {
                code: 401,
                msg: 'token不存在'
            }
            return
        }
    }
}

2⃣️ 在router.js引入中间件

const _jwt = middleware.jwtErr(app.config.jwt.secret); // 传入加密字符串
router.get('/api/user/getUserinfo', _jwt, controller.user.getUserInfo)

然后在请求获取用户信息接口, 如果不传token的话

image.png

这样就起到了拦截的作用

image.png

加上token则没有问题, 之后的删 改 查 都需要经过token验证才可以

6.修改用户

1⃣️ 在service目录下user.js新增函数

async editUserInfo(params) {
        const { app } = this
        try {
           // update代表更新, 第一个参数要更新的表, 第二个参数要更新的参数, 第三个参数找到要更新的对象
            const result = await app.mysql.update('user', {
                ...params
            }, {
                id: params.id
            })
            return result
        }catch(error) {
            console.log(error)
            return null
        }
    }

2⃣️ 在controller目录下user.js编辑函数

// 编辑用户
    async editUserInfo() {
        const { ctx, app } = this
        const { signature = '', avatar = '' } = ctx.request.body
        try {
            let user_id
            const token = ctx.request.header.authorization
            const decode = await app.jwt.verify(token, app.config.jwt.secret)
            if(!decode) return
            user_id = decode.id
            const userInfo = await ctx.service.user.getUserByName(decode.username)
            let newObj = {
                ...userInfo,
                signature, 
                avatar
            }
            const result = await ctx.service.user.editUserInfo(newObj)
            ctx.body = {
                code: 200, 
                msg: '请求成功',
                data: {
                    id: user_id,
                    signature,
                    username: userInfo.username,
                    avatar
                }
            }
        }catch(error) {
            
        }
    }

3⃣️ 在router.js中添加路由

router.post('/api/user/editUserInfo', _jwt, controller.user.editUserInfo)

image.png

7.删除用户

1⃣️ 在service目录下user.js新增函数

async deleteUser(user_id) {
        const { app } = this   
        // 删除sql语句
        let sql = `delete from user where id = ${user_id}`
        try {
            const result = await app.mysql.query(sql)
            return result
        }catch(error) {
            console.log(error)
            return null
        }
    }

2⃣️ 在controller目录下user.js新增函数

// 删除用户
    async deleteUser() {
        const { ctx, app } = this
        const { id } = ctx.request.body
        try {
            const result = await ctx.service.user.deleteUser(id) 
            ctx.body = {
                code: 200,
                msg: '请求成功',
                data: result
            }
        }catch(error) {
            ctx.body = {
                code: 500,
                msg: '业务异常',
                data: error
            }
        }
    }

3⃣️ 在router.js中添加路由

  router.post('/api/user/deleteUser', _jwt, controller.user.deleteUser)

image.png

8.查询用户列表

1⃣️ 首先向数据库插入几条数据

image.png

2⃣️ 在service目录下user.js新增函数

 async getUserList (pageIndex, pageSize) {
        const { ctx, app } = this
        const QUERY_STR = 'id, username'
        let sql = `select ${QUERY_STR} from user limit ?,?`
        try {
            // 根据分页查询数据库对应数据, 假如pageIndex = 2 , pageSize = 3 则查询的第二页的数据,查的是索引为3到5的数据
            const result = await app.mysql.query(sql, [(pageIndex - 1) * pageSize, pageIndex * pageSize])
            return result
        }catch(error) {
            console.log(error)
            return null
        }
    }

3⃣️ 在controller目录下user.js新增函数

 // 获取用户列表
    async getUserList() {
        const { ctx } = this
        const { pageIndex = 1, pageSize = 3} = ctx.request.query
        try {
            let list =  await ctx.service.user.getUserList(pageIndex, pageSize)
            ctx.body = {
                code: 200,
                msg: '请求成功',
                data: list
            }
        }catch(error) {
            ctx.body = {
                code: 500,
                msg: '请求失败',
                data: null
            }
        }
    }

image.png