基于node.js + express框架实现的简单服务端(二)

  • 一、前言
  • 二、创建数据表
  • 1.创建clientModel.ts脚本
  • 2.创建数据结构
  • 3.导出模块
  • 三、数据操作
  • 1.创建clientOperation.ts脚本
  • 2.引用express,clientModel模块
  • 3.添加数据
  • 4.查找数据
  • 5.更新数据
  • 6.删除数据
  • 四、Controller控制调用
  • 1.导入模块
  • 2.创建ClientOperation实例
  • 3.调用ClientOperation方法
  • 4.导出模块


一、前言

本文主要写后端中与数据库相关的操作,将以Client用户为说明对象,详细说明在项目中如何来进行像建表、数据的增删改查等操作。

二、创建数据表

1.创建clientModel.ts脚本

在Model文件下创建clientModel脚本,用来编写Client数据表的数据结构。

2.创建数据结构

先导入mongoose包

Import mongoose from “mongoose”;

定义Schema变量

const Schema = mongoose.Schema;

定义Client数据结构

const ClientSchema = new Schema({
    userName: {
        type: String,
        unique: true
    },
    password: {
        type: String
    },
    clientType: {
        type: Number,
    }
});

其中userName,password,clientType为client对象拥有的属性名称,可以根据自己的需求来定义属性,这些只作参考。type表示属性的类型,像String,Number,Array等等,unique为true表示该属性的值是唯一的,不能重复,对于属性的设置详情,可参考mongoose的官方文档中对于Schema的介绍,文档链接:https://mongoosejs.com/docs/schematypes.html

3.导出模块

导出定义的Client数据结构,可在外部其他脚本中引用。

export const ClientModel = mongoose.model("clients", ClientSchema);

mongoose.model(“clients”, ClientSchema);表示在数据库创建名称为clients的表,这里有两种写法,这种是简化的写法,另一种是mongoose.model(“clients”, ClientSchema,“clients”);这个是完整的写法,第一个”clients”表示这个表在当前程序集中的引用名称,第二个”clients”表示在数据库中的表的名称,注意必须与数据库中的表名称一致,否则会找不到对应的表。大部分情况写第一种的简化版就可以了,但是有时候是需要些第二种的,我遇到过一个问题,些简化版无法取到数据库中对应表的数据,改成第二种的完整版写法就没有这个问题,所以如果遇到无法取到表中的数据的情况,可以考虑改成第二种写法。
注意:在执行mongoose.model()操作的时候,若是数据库中没有对应的表,则会自动在数据库中创建一个表,若是数据库中已经有这个表,则不会创建新的表。
完整代码如下:

import mongoose from "mongoose";

const Schema = mongoose.Schema;

const ClientSchema = new Schema({
    userName: {
        type: String,
        unique: true
    },
    password: {
        type: String
    },
    clientType: {
        type: Number,
    }
});

export const ClientModel = mongoose.model("clients", ClientSchema);

三、数据操作

1.创建clientOperation.ts脚本

在DBOperations文件夹下创建clientOperation脚本,用来编写实际的数据库操作脚本。

2.引用express,clientModel模块

import { Request, Response } from "express";
import { ClientModel } from "../Models/clientModel";

因为后续在操作数据库的时候是需要根据前端发送的请求数据来处理,所以这里导入了express的Request,Response模块,来进行网路请求处理。

3.添加数据

首先创建ClientModel表的实例,再通过实例方法save来实现数据的创建存储。代码如下:

createClient = async (req: Request, res: Response) => {
        const clients = new ClientModel(req.body);

        try {
            const data = await clients.save();

            res.send(data);
        }
        catch (err) {
            console.log(err);
        }
}

因为在执行完创建操作之后需要给前端返回结果,而在数据库中进行数据操作是个过程,所以需要进行异步存储操作,这里使用的是async和await来实现。前端在发送创建请求的时候,数据是存放在req中的body字段的,所以这里在创建ClientModel的实例时传入的参数是req.body。关于网络请求的字段,请自行查找相关资料了解,这里不做说明。
创建的结果data包含你所创建的这条数据在数据库中的所有属性,在MongoDB中创建数据,会默认给数据添加一个_id属性来作为数据的标识,_id的类型是objectId,他是MongoDB系统的类型。
如果你所传的数据在ClientModel脚本中没有定义,那在数据库中添加数据时会自动添加这个属性,如果ClientModel中定义的一些属性,你在请求数据中没有传,那么这些属性在数据库存储时是不会显示的。

4.查找数据

通过ClientModel.findOne()方法来实现,代码如下:

getClient = async (req: Request, res: Response) => {
        try {
            const data = await ClientModel.findOne({ _id: req.query.clientId });

            res.send(data);
        }
        catch (err) {
            console.log(err);
        }
}

findOne方法传入的参数是具体的查询条件,可以是多个条件参数{···,···,···}。查询的结果data,就是你在数据库中符合查询条件的那条数据的所有属性内容。findOne是只查询一条结果,如果需要查询多条结果可以直接使用find方法,用法一样。具体介绍可以参考mongoose官方文档说明。

5.更新数据

通过ClientModel.findOneAndUpdate()方法来实现。代码如下:

updateClient = async (req: Request, res: Response) => {
        try {
            const data = await ClientModel.findOneAndUpdate({ _id: req.query.clientId }, req.body, { new: true });

            res.send(data);
        }
        catch (err) {
            console.log(err);
        }
}

传的第一个参数是查找目标数据的条件,第二个参数是要更新的数据,第三个属性为true表示操作的结果data是更新之后的新数据,为false表示data是未更新前的原始数据。

6.删除数据

通过ClientModel.deleteOne()方法来实现。代码如下:

deleteClient = async (req: Request, res: Response) => {
        try {
            await ClientModel.deleteOne({ _id: req.query.clientId });

            res.send("delete success!");
        }
        catch (err) {
            console.log(err);
        }
}

因为delete的操作结果没有什么可用的内容,这里没有写操作结果data,给前端只返回了一个字符串“delete success!”表示删除操作完成。

四、Controller控制调用

添加ClientController脚本的目的是在路由层和数据操作之间加一层转接层,避免路由请求直接进行数据库操作,这样便于后期维护,也利于后期进行功能拓展。

1.导入模块

import { Request, Response } from "express";
import { ClientOperation } from "../DBOperations/clientOperation";

2.创建ClientOperation实例

首先创建ClientOperation类型的变量,然后在构造函数中创建ClientOperation对象实例。

private clientOperation = null;

constructor() {
	this.clientOperation = new ClientOperation();
}

3.调用ClientOperation方法

getClient = (req: Request, res: Response) => {
        try{
            this.clientOperation.getClient(req, res);
        }
        catch(err){
            console.log(err);
        }
}

同样的形式,给其他几种操作添加调用方法即可。

4.导出模块

export class ClientController

这样对于数据库的操作部分就写完了,接下来会写对前端请求的路由处理,以及如何来调用这些数据操作方法。文章后续会继续更新。