当前位置: 首页 > 后端技术 > Node.js

一个巧妙的对象映射关系设计--JSON-ORM

时间:2023-04-03 11:31:52 Node.js

项目介绍这是标准数据库封装的上半部分,实现智能查询(JSON-ORM)。完整代码:https://github.com/zhoutk/gels设计思路我们常见的ORM,基本模型就是要和数据库分离,几乎所有的模型都是在编程语言层面构建的,程序和数据库打交道。虽然我们脱离了数据库的具体操作,但是需要创建各种模型文档,用代码写表之间的关系等操作,这让初学者一时如云。我的想法是将关系数据库所拥有的综合设计工具的优势与微服务结合起来。数据设计提供结构信息;从前端发送到后端的json对象自动映射成标准的SQL查询语句。只要了解标准的SQL语言,就可以完成数据库的查询操作。在我的ORM方式中,服务端不需要写一行代码,只需要完成关系数据库的设计,为前端提供一个标准的服务接口。并且遵循一套统一的接口(经过实践检验,满足99%的查询需求)实现数据库封装,让业务层可以随意切换数据库。数据库查询操作界面。导出默认接口IDao{select(tablename:string,params:object,fields?:Array):Promise;//自动生成sql语句execSql(sql:string,values:Array,params:object,fields?:Array):Promise;//执行手动sql语句}智能查询(JSON-ORM)查询保留字:fields,page,size,sort,search,lks,ins,ors,count,sum,groupfields,定义查询结果字段,支持数组两种形式和逗号分隔的字符串,前端决定返回的数据库字段信息,这样后端的设计可以应用到更广泛的范围,不会造成网络带宽的浪费。在KOA2的框架下,GET请求必须支持输入数组,同一个key只能输入多次,比如:age=11&age=22。这样很不方便,我实现了一个参数转换函数,为数组提供多种输入形式。arryParsearryParse(arr):Array|null{//返回值为数据或nulltr??y{if(Array.isArray(arr)||G.L.isNull(arr)){//如果输入为数组或空,直接returnreturnarr}elseif(typeofarr==='string'){//如果是字符串if(arr.startsWith('[')){//数组的字符串形式,转换arr=JSON.parse(arr)}else{//一个逗号拼接的字符串,mysql驱动也支持以字符串或者数组的形式提供参数,//所以这里可以直接使用split函数将字符串转换为数组arr=arr.split(',')}}}catch(err){arr=null//数组的字符串形式转换失败,刘明输入参数错误}returnarr}查询示例:请求URL:/rs/users?username=white&age=22&fields=["username","age"]生成sql:SELECTusername,ageFROMusersWHEREusername=?而age=?page,size,sort,分页排序在mysql中比较容易实现,limit做分页很方便。排序的话,只需要将参数直接拼接成orderby即可。查询示例:请求URL:/rs/users?page=1&size=10&sort=agedesc生成sql:SELECT*FROMusersORDERBYagedescLIMIT0,10search,模糊查询切换参数,不提供则提供字段查询进行精确匹配在精确匹配和模糊匹配之间切换的实现过程中,注意参数化参数和like匹配时在参数两边加%,而不是在占位符两边加%。另外,同一个字段匹配两个模糊查询,需要特殊处理。我提供了一个巧妙的方法://Encodethevaluewithescape,array将被转换为逗号连接的字符串,并用常规全局变量替换为andConnectionvalue=pool.escape(value).replace(/\',\'/g,"%'and"+key+"like'%")//去掉两端多余的引号value=value.substring(1,value.length-1)//完成条件查询语句,这种方法比使用循环处理更快,它统一了数组和其他形式的处理where+=key+"like'%"+value+"%'"查询示例请求URL:/rs/users?username=i&password=1&searchins,lks,ors这三个是最重要的查询方式。如何找出它们之间的共同点,减少冗余代码是关键。ins,查询中的数据库表单字段,一个字段对多个值,例如:查询示例:请求URL:/rs/users?ins=["age",11,22,26]生成sql:SELECT*FROMusersWHEREagein(?)ors,数据库表多字段精准查询,或连接,多字段多值,支持空值查询,示例:查询示例:请求URL:/rs/users?ors=["age",1,"age",22,"password",null]生成sql:SELECT*FROMusersWHERE(age=?orage=?orpasswordisnull)lks,数据库表多字段模糊查询,或连接,多字段对Multiplevalues,支持空值查询,示例:查询示例:请求URL:/rs/users?lks=["username","i","password",null]生成sql:SELECT*FROMusersWHERE(usernamelike?orpasswordisnull)count,sum,这两个统计的总和,处理方法类似,一般在查询的时候配合group和fields使用。count,数据库查询函数count,行统计,例如:查询示例:请求URL:/rs/users?count=["1","total"]&fields=["username"]生成sql:SELECTusername,count(1)astotalFROMusersum,数据库查询函数sum,字段sum,例子:查询例子:请求URL:/rs/users?sum=["age","ageSum"]&fields=["username"]group,databasegroupingFunctiongroup,example:queryexample:requestURL:/rs/users?group=age&count=["*","total"]&fields=["age"]生成sql:SELECTage,count(*)astotalFROMusersGROUPBY年龄不等运算符查询支持以下不等运算符:>、>=、<、<=、<>、=;逗号是分隔符,一个字段支持一个或两个操作。特点:使用“=”使一个字段跳过搜索效果,使模糊匹配和精确匹配出现在一条查询语句、一个字段、一次操作中,示例:查询示例:请求URL:/rs/users?age=>,10生成sql:SELECT*FROMusersWHEREage>?一个字段两个操作,例子:查询例子:请求URL:/rs/users?age=>,10,<=,35生成sql:SELECT*FROMusersWHEREage>?和年龄<=?使用“=”去掉字段的搜索效果,例子:查询例子:请求URL:/rs/users?age==,22&username=i&search生成sql:SELECT*FROMusersWHEREage=?andusernamelike?相关视频课程使用typescriptfornode.js后端开发精要nodejs实用智能微服务快速开发框架JSON-ORM(对象关系映射)设计与实现资源地址凝胶(gels)项目:https://github。com/zhoutk/gels视频讲座资料:https://github.com/zhoutk/sifou个人博客:https://segmentfault.com/blog...