likes
comments
collection
share

什么!Golang里两行代码就能搞定增删查改接口了?OQM技术与传统的ORM技术的最大区别是,OQM技术能通过对象直接构

作者站长头像
站长
· 阅读数 23

这都得益于OQM(Object Query-Language Mapping)技术的加持,我们开发了一个Go版本的实现,GoooQo

原理介绍

OQM技术与传统的ORM(Object Relational Mapping)技术的最大区别是,OQM技术提出直接基于对象构造各种增删查改语句。

其中,最核心的功能就是通过查询对象构建查询子句,这也是OQM名字中Q的由来。

OQM技术中另一个重要的发现就是查询对象的字段名称和查询子句的查询条件可以相互转换

例如SQL中的查询条件age > ?,我们只需要将>改写为字符串别名Gt(Greater-Than的缩写),再将Gt作为后缀附在列名age后得到ageGt,即可用作字段的名称。

然后我们使用OQM技术对这样的对象进行解析,在遇到名称为ageGt的字段被赋值时,只需要逆向进行上述过程就能得到对应的查询条件。

这样,我们只需要创建一个实体对象和一个查询对象,通过实体对象来确定表名和列名,通过在查询对象中定义字段和赋值来控制查询子句的构造。再将各种样板代码进行封装后,为单张表构建增删查改接口的代码就只剩下两行了。

Demo介绍

我们单独开发了一个demo来演示GoooQo的这项功能。

其中,test.db 是一个 sqlite 数据库,包含一个有4行数据的表t_user

idusernamepasswordemailmobilenicknamememovalid
1f0rb123456f0rb@163.com18888888881test11
2user2123456test2@qq.com18888888882test20
3user3123456test3@qq.com18888888883test3memo1
4user4123456test4@qq.com18888888884test41

接着我们在 user.go 中为user表定义两个结构体 UserEntityUserQuery

UserEntity就是一个传统的实体对象,字段对应上述表中的列名。

UserQuery中的字段按照列名加后缀的格式定义,以便生成对应的查询语句(字段后缀请参考文末的后缀映射表):

type UserQuery struct {
    goooqo.PageQuery
    IdGt         *int     // id > ?
    IdIn         *[]int   // id IN (?,?,?)
    EmailContain *string  // email LIKE "%value%"
    MemoNull     *bool    // memo is [NOT] NULL
}

此外,嵌入的goooqo.PageQuery中定义了PageNumberPageSizeSort3个字段,用于构造分页子句和排序子句。

接下来,在main方法里建立好数据库连接后,我们即可使用下面两行代码来为user表构建一个增删查改接口:

userDataAccess := rdb.NewTxDataAccess[UserEntity](tm)
goooqo.BuildRestService[UserEntity, UserQuery]("/user/", userDataAccess)

其中,第一行代码为user表创建一个数据库访问模块,第二行代码使用创建的数据库访问模块为user表创建一个web访问模块。

这个web访问模块负责处理 http://localhost:9090/user/ 上的访问请求。

Demo运行

demo仓库的代码克隆到本地,运行demo.go文件里的main方法启动程序,然后访问以下地址即可查看请求结果:

对于查询参数?emailContain=qq&memoNull=false,将会生成SQL语句SELECT * FROM t_user WHERE email LIKE '%qq' AND memo IS NOT NULL,对应的返回结果为:

{
  "data": {
    "list": [
      {
        "id": 3,
        "username": "user3",
        "email": "test3@qq.com",
        "mobile": "18888888883",
        "nickname": "test3",
        "memo": "memo",
        "valid": true
      }
    ],
    "total": 1
  },
  "success": true
}

我们还可以使用user.http文件里提供的HTTP请求来测试 POST/PUT/PATCH/DELETE 等接口. 例如:

### 添加新的user
POST http://localhost:9090/user/
Content-Type: application/json

[{
  "username": "Ada Wong",
  "email": "AdaW@gmail.com",
  "mobile": "01066666",
  "nickname": "ada",
  "memo": "An agent.",
  "valid": true
}, {
  "username": "Leon Kennedy",
  "email": "LeonKennedy@gmail.com",
  "mobile": "01077777",
  "nickname": "leon",
  "memo": "The hero.",
  "valid": true
}]

### 为id为3的用户更新指定字段

PATCH http://localhost:9090/user/3
Content-Type: application/json

{
  "username": "Leon Kennedy",
  "email": "LeonKennedy@gmail.com"
}

### 删除memo字段为NULL的用户
DELETE http://localhost:9090/user/?memoNull=false

后记

GoooQo是OQM技术在继Java版框架DoytoQuery之后的Go语言版本,现在还只是一个得到初步验证的MVP,后续还需多轮迭代才能实现OQM技术提出的所有特性。请大家保持关注,多多支持!

附录:后缀映射表

当前版本支持的后缀以及对应的查询条件可以参考这张后缀映射表:

后缀名称字段名称字段赋值SQL查询条件MongoDB查询条件
(EMPTY)id5id = 5{"id":5}
EqidEq5id = 5{"idEq":5}
NotidNot5id != 5{"idNot":{"$ne":5}}
NeidNe5id <> 5{"idNe":{"$ne":5}}
GtidGt5id > 5{"idGt":{"$gt":5}}
GeidGe5id >= 5{"idGe":{"$gte":5}}
LtidLt5id < 5{"idLt":{"$lt":5}}
LeidLe5id <= 5{"idLe":{"$lte":5}}
NotInidNotIn[1,2,3]id NOT IN (1,2,3){"id":{"$nin":[1, 2, 3]}}
InidIn[1,2,3]id IN (1,2,3){"id":{"$in":[1, 2, 3]}}
NullmemoNullfalsememo IS NOT NULL{"memo":{"$not":{"$type", 10}}}
NullmemoNulltruememo IS NULL{"memo":{"$type", 10}}
NotLikenameNotLike"arg"name NOT LIKE '%arg%'{"name":{"$not":{"$regex":"arg"}}}
LikenameLike"arg"name LIKE '%arg%'{"name":{"$regex":"arg"}}
NotStartnameNotStart"arg"name NOT LIKE 'arg%'{"name":{"$not":{"$regex":"^arg"}}}
StartnameStart"arg"name LIKE 'arg%'{"name":{"$regex":"^arg"}}
NotEndnameNotEnd"arg"name NOT LIKE '%arg'{"name":{"$not":{"$regex":"arg$"}}}
EndnameEnd"arg"name LIKE '%arg'{"name":{"$regex":"arg$"}}
NotContainnameNotContain"arg"name NOT LIKE '%arg%’{"name":{"$not":{"$regex":"arg"}}}
ContainnameContain"arg"name LIKE '%arg%’{"name":{"$regex":"arg"}}
RxnameRx"arg\d"name REGEXP 'arg\d’{"name":{"$regex":"arg\d"}}

原文链接:blog.doyto.win/post/introd…

© 2024 Yuan Zhen. All rights reserved.

转载自:https://juejin.cn/post/7406900130764881972
评论
请登录