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

栏目: 数据库 · 发布时间: 6年前

内容简介:这是标准数据库封装的上半部分,智能查询(JSON-ORM)的实现。完整代码:我们通用的ORM,基本模式都是想要脱离数据库的,几乎都在编程语言层面建立模型,由程序去与数据库打交道。虽然脱离了数据库的具体操作,但我们要建立各种模型文档,用代码去写表之间的关系等等操作,让初学者一时如坠云雾。我的想法是,将关系数据库拥有的完善设计工具之优势与微服务结合起来,数据设计提供结构信息;前端送到后端的json对象自动映射成为标准的SQL查询语句。只要我们理解了标准的SQL语言,我们就能够完成数据库查询操作。我的这种ORM

项目介绍

这是标准数据库封装的上半部分,智能查询(JSON-ORM)的实现。完整代码: https://github.com/zhoutk/gels

设计思路

我们通用的ORM,基本模式都是想要脱离数据库的,几乎都在编程语言层面建立模型,由程序去与数据库打交道。虽然脱离了数据库的具体操作,但我们要建立各种模型文档,用代码去写表之间的关系等等操作,让初学者一时如坠云雾。我的想法是,将关系数据库拥有的完善设计 工具 之优势与微服务结合起来,数据设计提供结构信息;前端送到后端的json对象自动映射成为标准的 SQL 查询语句。只要我们理解了标准的SQL语言,我们就能够完成数据库查询操作。我的这种ORM方式,服务端不需要写一行代码,只需完成关系数据库的设计,就能为前端提供标准服务接口。并且遵循一套统一的接口(已经实践检验,满足百分之九九的查询需求)来实现数据库封装,达到业务层可以随意切换数据库的目的。

数据库查询操作接口。

export default interface IDao {
    select(tablename: string, params: object, fields?: Array<string>): Promise<any>;                            //自动生成sql语句
    execSql(sql: string, values: Array<any>, params: object, fields?: Array<string>): Promise<any>;             //执行手动sql语句
}

智能查询(JSON-ORM)

查询保留字:fields, page, size, sort, search, lks, ins, ors, count, sum, group

  • fields, 定义查询结果字段,支持数组和逗号分隔字符串两种形式

    由前端来确定返回的数据库字段信息,这样后端的设计可以适用面更广泛,而不会造成网络带宽的浪费。

    在KOA2的框架下,GET请求要支持输入数组,只能把同一个key多次输入,如:age=11&age=22。这样很不方便,我实现了一个参数转换函数,针对数组提供多种输入形式。

    arryParse

    arryParse(arr): Array<any>|null {                      //返回值为数据或空值
            try {
                if (Array.isArray(arr) || G.L.isNull(arr)) {   //如果输入是数组或空,直接返回
                    return arr
                } else if (typeof arr === 'string') {          //若是字符串
                    if (arr.startsWith('[')) {                 //数组的字符串形式,进行转换
                        arr = JSON.parse(arr)
                    } else {
                        //逗号拼接的字符串,mysql的驱动同时支持参数以字符串形式或数组形式提供,
                        //所以这里可以不加判断,直接用split函数将字符串转化为数组
                        arr = arr.split(',')                   
                    }
                }
            } catch (err) {
                arr = null            //数组的字符串形式转换失败,刘明输入参数是错误的
            }
            return arr
        }

    查询示例:

    请求URL:  /rs/users?username=white&age=22&fields=["username","age"]
    生成sql:   SELECT username,age FROM users  WHERE username = ?  and age = ?
  • page, size, sort, 分页排序

    mysql 中这比较好实现,limit来分页是很方便的,排序只需将参数直接拼接到order by后就好了。

    查询示例:

    请求URL:  /rs/users?page=1&size=10&sort=age desc
    生成sql:   SELECT * FROM users  ORDER BY age desc LIMIT 0,10
  • search, 模糊查询切换参数,不提供时为精确匹配

    提供字段查询的精确匹配与模糊匹配的切换,实现过程中,注意参数化送入参数时,like匹配,是要在参数两边加%,而不是在占位符两边加%。

    另外,同一个字段匹配两次模糊查询,需要特别处理,我提供了一种巧妙的方法:

    //将值用escape编码,数组将转化为逗号连接的字符串,用正则全局替换,变成and连接
    value = 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&search
  • ins, lks, ors

    这是最重要的三种查询方式,如何找出它们之间的共同点,减少冗余代码是关键。

    • ins, 数据库表单字段in查询,一字段对多个值,例:

      查询示例:

      请求URL:  /rs/users?ins=["age",11,22,26]
      生成sql:   SELECT * FROM users  WHERE age in ( ? )
    • ors, 数据库表多字段精确查询,or连接,多个字段对多个值,支持null值查询,例:

      查询示例:

      请求URL:  /rs/users?ors=["age",1,"age",22,"password",null]
      生成sql:   SELECT * FROM users  WHERE  ( age = ?  or age = ?  or password is null )
    • lks, 数据库表多字段模糊查询,or连接,多个字段对多个值,支持null值查询,例:

      查询示例:

      请求URL:  /rs/users?lks=["username","i","password",null]
      生成sql:   SELECT * FROM users  WHERE  ( username like ?  or password is null  )
  • count, sum

    这两个统计求和,处理方式也类似,查询时一般要配合group与fields使用。

    • count, 数据库查询函数count,行统计,例:

      查询示例:

      请求URL:  /rs/users?count=["1","total"]&fields=["username"]
      生成sql:   SELECT username,count(1) as total  FROM users
    • sum, 数据库查询函数sum,字段求和,例:

      查询示例:

      请求URL:  /rs/users?sum=["age","ageSum"]&fields=["username"]
  • group, 数据库分组函数group,例:

    查询示例:

    请求URL:  /rs/users?group=age&count=["*","total"]&fields=["age"]
    生成sql:   SELECT age,count(*) as total  FROM users  GROUP BY age

不等操作符查询支持

支持的不等操作符有:>, >=, <, <=, <>, =;逗号符为分隔符,一个字段支持一或二个操作。

特殊处:使用"="可以使某个字段跳过search影响,让模糊匹配与精确匹配同时出现在一个查询语句中

  • 一个字段一个操作,示例:

    查询示例:

    请求URL:  /rs/users?age=>,10
    生成sql:   SELECT * FROM users  WHERE age> ?
  • 一个字段二个操作,示例:

    查询示例:

    请求URL:  /rs/users?age=>,10,<=,35
    生成sql:   SELECT * FROM users  WHERE age> ? and age<= ?
  • 使用"="去除字段的search影响,示例:

    查询示例:

    请求URL:  /rs/users?age==,22&username=i&search
    生成sql:   SELECT * FROM users  WHERE age= ?  and username like ?

以上所述就是小编给大家介绍的《一种巧妙的对象映射关系设计--JSON-ORM》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Eloquent JavaScript

Eloquent JavaScript

Marijn Haverbeke / No Starch Press / 2011-2-3 / USD 29.95

Eloquent JavaScript is a guide to JavaScript that focuses on good programming techniques rather than offering a mish-mash of cut-and-paste effects. The author teaches you how to leverage JavaScript's......一起来看看 《Eloquent JavaScript》 这本书的介绍吧!

HTML 编码/解码
HTML 编码/解码

HTML 编码/解码

UNIX 时间戳转换
UNIX 时间戳转换

UNIX 时间戳转换

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具