前言:
现时朋友们对“虚拟sql数据库操作”大约比较关怀,小伙伴们都需要剖析一些“虚拟sql数据库操作”的相关知识。那么小编也在网络上收集了一些有关“虚拟sql数据库操作””的相关知识,希望大家能喜欢,各位老铁们一起来学习一下吧!一. 前言
作为程序员的我们,通常避免不了对需求任务的追赶。
而作为切图仔的我们,作为开发最后提测前最后一环的我们,对无法准时提测,有时候可能存在一些委屈,相信肯定遇到接口不及时而导致页面进度延期的情况。
此外,在日常迭代的规律性的迭代,前端很容易出现一种形象,就是出现"区间性"忙碌。你说非常忙,把工作日平摊下来,实际上也没多少产出,但就是在最后时刻特别忙碌。给人的一种感觉就是,联调前,没事做;联调后,事太多。
如果,有一款能生成虚拟的联调数据,是能分担任务的比重的。而前端mock就是在这种背景中产生。
二. mock的意义
说完mock存在的背景,这里再分析一下mock的意义。
1) 草图
如何解决前端任务不聚焦的问题,笔者这里简单梳理了一个草稿图:
2) 分析
上图已经列出,我们面对的问题:
1.当前只有业务逻辑(表结构),无法生成对应接口2.模拟数据成本高,无法快速生成3.有数据了,也无法进行真实增删改查
根据如上,笔者认为一个好用的mock工具,我觉得应该保证下边的功能:
1.能自定义我们的数据格式,返回对应的数据结构以及相关的字段等。2.能快速自定义我们的数据源。3.能快速生成增删改查的接口,模拟真实数据的运转,否则就失去了意义4.如果能根据表结构直接生成,那就更完美
当然,博客上,也有好多博主有自己的见解,有些东西我觉得可以非必要追求:
1.过于追求数据结构。假设没有技术评审,还未确认表结构,我们设计一个差不多就可以。这玩意再怎么优秀,都只是“模拟”数据而已,你永远猜不中后端最终给你的格式。2.实现复杂的逻辑。越复杂的逻辑,也表示花费的时间越多。只要接口有了,也意味着这玩意作废。所以,不适宜投入太高的成本。
这里也有几个前置条件:
BFF接口设计规范,我们知道对应的接口设计规范。对应业务的表结构3) 结论
综上分析,我们需要一款,配置"简单"且能"快速"生成一个增删改查的mock工具。而"简单"与"快速",是mock的核心。
三. 市场的常用方案
此时我们已经有了需求,再来看看市场的解决方案。一起看看,市场是怎么设计这些mock工具的,或者是有什么解决方案。
1)手动虚拟数据
该方案,直接在代码中写死 Mock 数据,或者请求本地的 JSON 文件。相信也是日常大家使用最多的方案。
优势:
上手快,无需学习成本。
劣势:
做数据比较麻烦。无法自动生成增删改查等。会使项目太多冗余数据,解藕也较难。2)接口管理工具
这里以swagger为例,相信后端是java的切图仔都看过这玩意。
优势:
自带接口规范。配置功能强大。根据后端接口生成。
劣势:
资源问题:毕竟是后端项目,启动一个后端项目也麻烦。还耗后端资源。人员问题:让后端帮忙处理,后端还不如直接加紧赶出接口给出来。配置问题:强大也意外着,学习成本高。熟悉一些配置相关的成本也不低。3)node服务器
结合上边,如果说使用一个java后端比较麻烦,那么启动一个Node服务器的话呢?
常见的有我们的koa,或者是express框架等等。
优势:
前端学习成本相对较低,毕竟都是js
劣势:
增删改查,还是需要手动写4)MOCKJS
优势:
可随机生成所需数据,可模拟对数据的增删改查
劣势:
可以实现增删改查, 数据源的确比较灵活,支持随机数,正则等,但是模拟数据麻烦一些。5)抓包工具
代表作Fiddler
优势:
脱离程序本身,可以直接映射,修改数据源。
劣势:
调试相对繁琐。定位并不是mock开发阶段,更适合偶尔模拟数据定位问题。
四.手动搭建自己的mock
介绍自己的Cb mock:
1)功能介绍能快速自定义我们的数据格式,能快速生成增删改查接口支持三种模式,自定义模式,json模式,sql模式支持接口校验,如必填,长度等校验能自定义返回接口格式,统一数据格式规范,项目也支持自定义规范与项目本身脱离解耦,可快速替换真实链接支持生成api文档说明2)核心技术栈/源码koa
启动koa服务,作为服务提供者,代码如下:
const Koa = require('koa')const app = new Koa();app.use(json())app.use(logger())app.use(koaBody());app.use(bodyParser({ enableTypes: ['json', 'form', 'text'], multipart: true}));复制代码2. mockjs
返回mock数据:
const { mock } = require("mockjs"); ctx.body = Result.info(mock(Object.assign(defaultResult, result)));复制代码3.commander指令
如启动commander指令:
const program = require('commander')program .command("startMock") .description("启动mock服务") .action((appName, options) => { startMock() })复制代码4. 正则sql转换
利用正则切割sql:
const nameMatch = line.match(' `(.*)`');const maxLengthMatch = line.match(' varchar\\((.*)\\) ');const defaultMatch = line.match(' DEFAULT \'(.*)\' ');const commentMatch = line.match(' COMMENT \'(.*)\',');const typePattern = / (?:\w+)(.*?) /;const typeMatch = line.match(typePattern, "$0");const requiredReg = /NOT NULL/.test(line); const key = nameMatch[1];const maxLength = maxLengthMatch && maxLengthMatch.length > 0 ? Number(maxLengthMatch[1]) : undefined;const required = !requiredReg;const defaultValue = defaultMatch && defaultMatch.length > 0 ? defaultMatch[1] : undefined;const comment = commentMatch && commentMatch.length > 0 ? commentMatch[1] : undefined;const typeDb = typeMatch && typeMatch.length > 0 ? typeMatch[0] : [];复制代码5. fs生成文档
利用fs生成文档文件:
// 生成文档 const generateDoc = (table, port) => { let str = ''; Object.keys(table).forEach(key => { str += `## ${key}模块 | 参数名称 | 参数说明 | 数据类型 | 长度(字节) | 是否必填 | 默认值 | | ------- | ------- | ------ | ----- | ------- | --------- | ` const { column } = table[key] column.forEach(item => { const name = item.key; const type = item.type; const comment = item.comment ? item.comment : '-'; const defaultValue = item.default ? item.default : '-'; const isRequired = item.required ? "是" : "否" const maxLength = item.maxLength ? item.maxLength : "-" str += `| ${name} | ${comment} | ${type} | ${maxLength} | ${isRequired} | ${defaultValue} |\n` }) // 获取接口名称 const apiList = getApiList(key); for (let i = 0; i < apiList.length; i++) { const { url, name, type } = apiList[i] str += `### http:/${url} 接口说明:${name} 请求类型: ${type} \n` } })复制代码五.使用配置1)安装本地
git clone installnpm link复制代码2)配置mock.config.js
module.exports = { common: {//支持公用配置 port: 8000, timeout: 0, rate: 1, }, sqlDataSource: [//支持sql数据源 ` CREATE TABLE \`jsh_depot\` ( \`id\` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', \`name\` varchar(20) DEFAULT NULL COMMENT '仓库名称', \`address\` varchar(50) DEFAULT NULL COMMENT '仓库地址', \`warehousing\` decimal(24,6) DEFAULT NULL COMMENT '仓储费', \`truckage\` decimal(24,6) DEFAULT NULL COMMENT '搬运费', \`type\` int DEFAULT NULL COMMENT '类型', \`sort\` varchar(10) DEFAULT NULL COMMENT '排序', \`remark\` varchar(100) DEFAULT NULL COMMENT '描述', \`principal\` bigint DEFAULT NULL COMMENT '负责人', \`tenant_id\` bigint DEFAULT NULL COMMENT '租户id', \`delete_Flag\` varchar(1) DEFAULT '0' COMMENT '删除标记,0未删除,1删除', \`is_default\` bit(1) DEFAULT NULL COMMENT '是否默认', PRIMARY KEY (\`id\`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb3 COMMENT='仓库表'; insert into \`jsh_depot\`(\`id\`,\`name\`,\`address\`,\`warehousing\`,\`truckage\`,\`type\`,\`sort\`,\`remark\`,\`principal\`,\`tenant_id\`,\`delete_Flag\`,\`is_default\`) values (14,'仓库1','dizhi','12.000000','12.000000',0,'1','描述',131,63,'0',''); insert into \`jsh_depot\`(\`id\`,\`name\`,\`address\`,\`warehousing\`,\`truckage\`,\`type\`,\`sort\`,\`remark\`,\`principal\`,\`tenant_id\`,\`delete_Flag\`,\`is_default\`) values (15,'仓库2','地址100','555.000000','666.000000',0,'2','dfdf',131,63,'0','\0'); insert into \`jsh_depot\`(\`id\`,\`name\`,\`address\`,\`warehousing\`,\`truckage\`,\`type\`,\`sort\`,\`remark\`,\`principal\`,\`tenant_id\`,\`delete_Flag\`,\`is_default\`) values (17,'仓库3','123123','123.000000','123.000000',0,'3','123',131,63,'0','\0'); CREATE TABLE \`jsh_depot22\` ( \`id\` bigint NOT NULL AUTO_INCREMENT COMMENT '主键', \`name\` varchar(20) DEFAULT NULL COMMENT '仓库名称', \`address\` varchar(50) DEFAULT NULL COMMENT '仓库地址', \`warehousing\` decimal(24,6) DEFAULT NULL COMMENT '仓储费', \`truckage\` decimal(24,6) DEFAULT NULL COMMENT '搬运费', \`type\` int DEFAULT NULL COMMENT '类型', \`sort\` varchar(10) DEFAULT NULL COMMENT '排序', \`remark\` varchar(100) DEFAULT NULL COMMENT '描述', \`principal\` bigint DEFAULT NULL COMMENT '负责人', \`tenant_id\` bigint DEFAULT NULL COMMENT '租户id', \`delete_Flag\` varchar(1) DEFAULT '0' COMMENT '删除标记,0未删除,1删除', \`is_default\` bit(1) DEFAULT NULL COMMENT '是否默认', PRIMARY KEY (\`id\`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8mb3 COMMENT='仓库表'; insert into \`jsh_depot\`(\`id\`,\`name\`,\`address\`,\`warehousing\`,\`truckage\`,\`type\`,\`sort\`,\`remark\`,\`principal\`,\`tenant_id\`,\`delete_Flag\`,\`is_default\`) values (14,'仓库1','dizhi','12.000000','12.000000',0,'1','描述',131,63,'0',''); insert into \`jsh_depot\`(\`id\`,\`name\`,\`address\`,\`warehousing\`,\`truckage\`,\`type\`,\`sort\`,\`remark\`,\`principal\`,\`tenant_id\`,\`delete_Flag\`,\`is_default\`) values (15,'仓库2','地址100','555.000000','666.000000',0,'2','dfdf',131,63,'0','\0'); insert into \`jsh_depot\`(\`id\`,\`name\`,\`address\`,\`warehousing\`,\`truckage\`,\`type\`,\`sort\`,\`remark\`,\`principal\`,\`tenant_id\`,\`delete_Flag\`,\`is_default\`) values (17,'仓库3','123123','123.000000','123.000000',0,'3','123',131,63,'0','\0'); ` ], jsonDataSource: [//支持json数据源 { account_detail: { column: [ "id", { key: 'username', required: true }, "auth_key", "password_hash", "password_reset_token", "email", "created_at", ], dataSource: [ { "id": 13, "email": "368938" }, [14, 45457] ], }, }, ], customDataSource: [[//支持自定义数据源 { url: "/login", returnFn: (req) => { const { name, password } = req.query; if (name === 'admin' || password === 'a123456') { return { status: 1, msg: "登录成功" } } return { status: 0, msg: "账号或密码错误" } } }, { url: "/addUser", type: "post", returnFn: (req) => { const { name } = req.request.body; if (name !== '' && name !== undefined) { return { status: 1, msg: "新增账号成功" } } return { status: 0, msg: "请输入用户名" } } }, ]};复制代码3)启动服务
cb startMock复制代码4)启动结果
会生成mock.md接口文档说明:
五.源码
github.com/zhuangweizh…
六.结语
时间仓促,一些功能未完善。分享一下未来计划:
支持sql的left join生成完成文档的生成欢迎反馈bug
标签: #虚拟sql数据库操作