本网站的架构(二)后端数据库

 0 0条评论

使用express框架,搭建典型的RESTFUL模式api。

数据库使用mongodb,并使用mongoose模块对数据库进行操作。

首先创建一个BaseSchema.js文件,所有实体都继承此Schemal,代码如下:

    const mongoose = require('mongoose')
    const Joi = require('@hapi/joi')
    const { UserName, EmptyUserName, ObjectID } = require('../modules/regexp')
    const createBaseSchema = () => {
      mongoose.set('useFindAndModify', false)
      return new mongoose.Schema({
        createDatetime: {
          type: Number,
          default: Date.now()                 //mongodb存储时间是格林威治时间,即比北京时间少8个小时。                //'2020-05-11T06:30:34.000Z',所以直接保存毫秒
        },
        modifyDatetime: {
          // 此字段会在 excute update操作时给与赋值
          type: Number
        },
        createUser: {
          // 此字段会在路由post方法时 根据 req.username给与赋值
          type: String,
          required: [true, '创建用户不能为空'],
          validate: {
            //自定义验证
            validator: (v) => {
              if (/^\d+$/.test(v)) return false //不能纯数字
              return UserName.test(v)
            },
            message: '{VALUE} 不是一个正确的用户名'
          }
        },
        modifyUser: {
          // 此字段会在路由put方法时 根据 req.username给与赋值
          type: String,
          default: '',
          validate: {
            //自定义验证
            validator: (v) => {
              if (/^\d+$/.test(v)) return false //不能纯数字
              return EmptyUserName.test(v)
            },
            message: '{VALUE} 不是一个正确的用户名'
          }
        },
        enable: {
          type: Boolean,
          default: true
        }
      })
    }
    const baseInsertJoi = Joi.object({
      //添加时候的基础验证
      createUser: Joi.string().regex(UserName),
      createDatetime: Joi.number(),
      enable: Joi.boolean()
    })

    const baseUpdateJoi = Joi.object({
      //编辑时候的基础验证
      _id: Joi.string().regex(ObjectID),
      modifyUser: Joi.string().allow('').regex(UserName),
      enable: Joi.boolean(),
      modifyDatetime: Joi.number()
    })
    module.exports = {
      createBaseSchema,
      baseInsertJoi,
      baseUpdateJoi
    }

以department这个表为例,创建department文件夹,再新建departmentModel.js文件,继承所有BaseSchema的属性,自己独有的属性则在此文件里添加,代码如下

    const mongoose = require('mongoose')
    const { createBaseSchema } = require('../BaseSchema')
    const catalogSchema = createBaseSchema().add({
      name: {
        type: String,
        required: [true, '名字不能为空'],
        unique: true,
        dropDups: true
      },
      router: {
        type: String,
        default: '',
        unique: true,
        required: [true, '路由不能为空'],
      },
      sort: {
        type: Number,
        default: 0
      }
    })
    module.exports = mongoose.model('catalog', catalogSchema)

再新建baseAction.js文件,包含了基础的增删改方法,所以实体都会实现里面的方法,代码如下:

    const {baseUpdateJoi } = require('./BaseSchema')
    class BaseModel {
      //构造函数
      constructor(mongooseModel, objModel, indertSchema, updateSchema) {
        this.mongooseModel = mongooseModel
        this.objModel = objModel
        this.indertSchema = indertSchema
        this.updateSchema = updateSchema
      }

      /**
       * 添加,需要构造函数传入对象
       */
      async insert() {
        try {
          let result = await this.indertSchema.validateAsync(this.objModel)
          result.createDatetime = Date.now()
          return this.mongooseModel.create(result)
        } catch (err) {
          throw err
        }
      }

      /**
       * 删除
       * @param {string} _id
       */
      delete(_id) {
        try {
          return this.mongooseModel.findByIdAndDelete(_id)
        } catch (err) {
          throw err
        }
      }

      /**
       * 根据ID查找
       */
      findOneByID(_id) {
        try {
          return this.mongooseModel.findById(_id)
        } catch (err) {
          throw err
        }
      }
      /**
       * 更新状态
       */
      async updateEnable() {
        try {
          this.objModel.modifyDatetime = Date.now()
          let result = await baseUpdateJoi.validateAsync(this.objModel)
          let _id = result._id
          return this.mongooseModel.updateOne({ _id }, result)
        } catch (err) {
          throw err
        }
      }

      /**
       * 更新  需要构造函数传入对象
       */
      async update() {
        try {
          this.objModel.modifyDatetime = Date.now()
          let result = await this.updateSchema.validateAsync(this.objModel)
          let _id = result._id
          return this.mongooseModel.updateOne({ _id }, result)
        } catch (err) {
          throw err
        }
      }
    }

    module.exports = BaseModel

同样以department表为例,添加excute.js文件

    const DepartMentModel = require('./departmentModel')
    const BaseModel = require('../BaseModel')
    const { baseInsertJoi, baseUpdateJoi } = require('../BaseSchema')
    const { EmptyPhoneMobile } = require('../../modules/regexp')
    const Joi = require('@hapi/joi')
    const util = require('util')
    const schemaObj = {
      sort: Joi.number().required(),
      name: Joi.string().required(),
      phone: Joi.string().allow('').regex(EmptyPhoneMobile)
    }
    const insertSchema = baseInsertJoi.keys(schemaObj)
    const updateSchema = baseUpdateJoi.keys(schemaObj)
    /**
     * 部门数据库操作类
     */
    class DepartMemt {
  //构造函数
      constructor(department) { //给父类构造函数传值
        this.mongooseModel = DepartMentModel 
        this.objModel = department
        this.indertSchema = insertSchema
        this.updateSchema = updateSchema
      }
      /**
       * 查找全部部门
       */
      findAll() {
        return DepartMentModel.find().sort('-sort')
      }

      /**
       * 查找全部可用部门
       */
      findEnable() {
        return DepartMentModel.find({ enable: true }).select('name').sort('-sort')
      }
    }
    util.inherits(DepartMemt, BaseModel) //继承公共数据库操作类

    module.exports = DepartMemtq

其他实体也是类似创建,在需要使用department的地方,引入模块,可以执行公共模块的方法,也能执行实体自己的方法,如下:

    const Department= require('department/excute')
    let department= new Department()
    department.findOneByID('id')
    department.delete('id')

下一篇,本网站的架构(三)API接口

本文作者:双黑

版权声明:本站文章欢迎链接分享,禁止全文转载!

游客