node简单实现持久层

989 阅读5分钟

前言

光阴似箭,日月如梭,转眼间2020年已经过去了一半。闲言少叙,先进行下自我介绍,我是一名合格的滴滴司机只是一个城市行者,还未达到城市英雄的地步,疫情期间,没什么收入了。只能凑合着写点代码维持生计。最近用了小半年的时间写了点东西,拿出来和大家分享下,也不知道有没有用,希望大家多给点意见,毕竟我不是外卖小哥,能力有限。

第一章:为什么要自己写东西?

  • 首先:对于前端的开发人员来说,服务端,以及数据库并不是那么了解,对于mysql 建表 等等一系列操作很吃力。主要是我不会写sql。画一个前端页面可能个把小时就搞定了,写接口、写sql等等 迟迟搞不定,搞定了还容易错。

  • 其次:很多单表查询或者几个表联合查询,很多时候都是复制粘贴改改字段,改改表名、每次都要写好烦,不想一味的板砖!

  • 再次:写完的sql有时候还是错的,或者需求一变原来的接口基本上都不能用了

  • 最后:之前没写过。想试试 node+express+typescript+ mysql

第二章:我写的东西是什么?

  • 【一】模型,看图说话

1.上图的每一个小球,代表是一个model, 也可以说是对应数据库的表。
2.球和球中间的线,代表的是模型和模型的关系。实线代表的是一对多,虚线代表的是多对一,多对多通过中间模型来实现。

1.模型有两个维度 基本属性(数据库的字段)和关联关系。
2. 在工程启动或者初始化模型的时候,会检查数据(MYSQL),对每一个模型的基本属性 进行增删改。

  • 【二】接口,上才艺!
export class Base extends Service {
  public modelbase: Array<string>;
  public base: Array<string>;
  public relation: any;
  public modelName: string;
  constructor(public model: any) {
    super();
    this.modelbase = model['modelbase']
    this.base = model['base']
    this.relation = model['relation']
    this.modelName = model['modelName']
  }
  @Method('/query')
  query(param?: object){
    ....
  }
  @Method('/add')
  add(param?: object){
    ....
  }
  @Method('/batchCascadeAdd')
  batchCascadeAdd(param?: object){
    ....
  }
 ...
}
export function service(): object {
  return getModel().then(res => {
    model = res
    let service: any = {}
    for (let m in model) {
      let base: any = new Base(model[m])
      innerService[`${m}`] = {}
      for (let key in base) {
        if (key.indexOf('/') > -1) {
          service[`${m.toLowerCase()}${key.toLowerCase().replace(/\//g, '')}`] = function (param: any) {
            return base[key].call(base, param)
          }
          innerService[`${m}`][`${key.replace(/\//g, '')}`] = (param: any) => {
            return base[key].call(base, param)
          }
        }
      }
    }
    return service
  })
}

export { innerService } 
1.当数据库检查完成后,会在内存中对所有模型进行初始化。
2.同时通过上述部分代码, 根据model动态的生成service
(1).add/增
(2).save/新增或者修改
(3).del/删
(4).update/改
(5).batchCascadeAdd/批量级联增加修改
(6).batchCascadeDelete/批量级联删除
(7).queryall/无限级联查询
(8).query/根据条件查响应的关系(一对多或者多对一,分页多)、条件条件查询接口
function readFold(foldPath: string) {
  fs.readdir(__dirname + foldPath, (_err, _files): void => {
    if (_err) {
      console.log(_err);
      return
    }
    for (const item of _files) {
      const module = require(`./modules/${item}`).default
      const method: any = {}
      for (let key in module) {
        if (key.indexOf('/') > -1) {
          method[key.toLowerCase().replace(/\//g, '')] = function (param: any) {
            return module[key].call(module, param)
          }
        }
      }
      poollocal = Object.assign(method, poollocal)
    }
    logger.info('local API is load')
  });
  pool = Object.assign(poolbase, poollocal)
}

import express from 'express'
import { Adapter } from './adapter'
const router = express.Router()


router.get(/$/, Adapter)
router.post(/$/, Adapter)


export default router

遍历module 文件夹,把自动生成的接口和自己写的接口 统一放在Adapter里。这样再也不用一个一个接口去定义了。

PS: 动态模型的接口都注册确实有点性能上的浪费,动态生成有很多可能用不上,应该改成手动配置的。

  • 【三】来吧,展示,结果!

上图是不带任何条件的query

上边model 部分忘记介绍了,那就在这里补上吧!

之前说过两个球之间的线 代表着关联关系 看第一张球图:
user和userGroup 多对一
userGroup和user 一对多

在查询的时候只需要 增加一个参数{path:['路径名']} 就能关联出响应的 相关模型数据

  • 如:user和userGroup 多对一 结果为:
  • userGroup 是object
[
            {
                "id": "fd87ad6fe1343c9af65353496bbb7a5a",
                "createTime": "2020-06-23T08:14:37.000Z",
                "updateTime": "2020-06-23T08:14:37.000Z",
                "status": "status_able",
                "area": "33",
                "tel": "12",
                "relName": "2",
                "userName": "ddd ",
                "userGroupId": "570ce153a1343c998c198b9e76b90a7f",
                "userGroup": {
                    "id": "570ce153a1343c998c198b9e76b90a7f",
                    "createTime": "2020-06-22T01:18:15.000Z",
                    "updateTime": "2020-06-22T01:18:15.000Z",
                    "groupName": "用户组1"
                }
            },
            {
                "id": "5240b26dc1343c9af6337f1134612eb7",
                "createTime": "2020-06-23T08:13:50.000Z",
                "updateTime": "2020-06-23T08:13:50.000Z",
                "status": "status_disable",
                "area": "d",
                "tel": "128390",
                "relName": "阿圣诞节快乐",
                "userName": "张三1",
                "userGroupId": "e53f136231343c99a060770d6ea4bb67",
                "userGroup": {
                    "id": "e53f136231343c99a060770d6ea4bb67",
                    "createTime": "2020-06-22T02:51:04.000Z",
                    "updateTime": "2020-06-22T02:51:04.000Z",
                    "groupName": "www"
                }
            }
        ]

  • 如:userGroup和user多对一 结果为:
  • userGroup 是 数组
[
            {
                "id": "e53f136231343c99a060770d6ea4bb67",
                "createTime": "2020-06-22T02:51:04.000Z",
                "updateTime": "2020-06-22T02:51:04.000Z",
                "groupName": "www",
                "user": [
                    {
                        "id": "5240b26dc1343c9af6337f1134612eb7",
                        "createTime": "2020-06-23T08:13:50.000Z",
                        "updateTime": "2020-06-23T08:13:50.000Z",
                        "status": "status_disable",
                        "area": "d",
                        "tel": "128390",
                        "relName": "阿圣诞节快乐",
                        "userName": "张三1",
                        "userGroupId": "e53f136231343c99a060770d6ea4bb67"
                    }
                ]
            },
            {
                "id": "570ce153a1343c998c198b9e76b90a7f",
                "createTime": "2020-06-22T01:18:15.000Z",
                "updateTime": "2020-06-22T01:18:15.000Z",
                "groupName": "用户组1",
                "user": [
                    {
                        "id": "fd87ad6fe1343c9af65353496bbb7a5a",
                        "createTime": "2020-06-23T08:14:37.000Z",
                        "updateTime": "2020-06-23T08:14:37.000Z",
                        "status": "status_able",
                        "area": "33",
                        "tel": "12",
                        "relName": "2",
                        "userName": "ddd ",
                        "userGroupId": "570ce153a1343c998c198b9e76b90a7f"
                    }
                ]
            }
        ]

第三章:代码放哪里了?

重点来了!!!
重点来了!!!
重点来了!!!

Github:star直通车

界面地址

ps: 来掘金这么久了第一次写文章,希望大家能提点宝贵意见。

看都看到这了,不花钱的star 点一点、评论走一波!感谢!