如何用Go实现一个ORM

为了提高开发效率和质量,我们常常需要ORM来帮助我们快速实现持久层增删改查API,目前go语言实现的ORM有很多种,他们都有自己的优劣点,有的实现简单,有的功能复杂,有的API十分优雅。在使用了多个类似的工具之后,总是会发现某些点无法满足解决我们生产环境中碰到的实际问题,比如无法集成公司内部的监控,Trace组件,没有database层的超时设置,没有熔断等,所以有必要公司自己内部实现一款满足我们可自定义开发的ORM,好用的生产工具常常能够对生产力产生飞跃式的提升。,首先看看用database/sql如何查询数据库我们用user表来做例子,一般的工作流程是先做技术方案,其中排在比较前面的是数据库表的设计,大部分公司应该有严格的数据库权限控制,不会给线上程序使用比较危险的操作权限,比如创建删除数据库,表,删除数据等。表结构如下:,首先我们要写出和表结构对应的结构体User,如果你足够勤奋和努力,相应的json tag 和注释都可以写上,这个过程无聊且重复,因为在设计表结构的时候你已经写过一遍了。,定义好结构体,我们写一个查询年龄在20以下且按照id字段顺序排序的前20名用户的 go代码,当我们写少量这样的代码的时候我们可能还觉得轻松,但是当你业务工期排的很紧,并且要写大量的定制化查询的时候,这样的重复代码会越来越多。上面的的代码我们发现有这么几个问题:,我们总结出来用database/sql标准库开发的痛点:,很显然写上面的那种代码是很耗费时间的,因为手误容易写错,无可避免要增加自测的时间。如果上面的结构体User、 查询方法FindUsers() 代码能够自动生成,那么那将会极大的提高开发效率并且减少human error的发生从而提高开发质量。,如果一个开发人员把大量的时间花在这些代码上,那么他其实是在浪费自己的时间,不管在工作中还是在个人项目中,应该把重点花在架构设计,业务逻辑设计,困难点攻坚上面,去探索和开拓自己没有经验的领域,这块Dao层的代码最好在10分钟内完成。,明白了上面的痛点,为了开发工作更舒服,更高效,我们尝试着自己去开发一个ORM,核心的地方在于两个方面:,图片,我们尝试做个简略版的查询语句构造器,最终我们要达到如下图所示的效果。,图片,我们可以通过和SQL关键字同名的方法来表达SQL语句的固有关键字,通过go方法参数来设置其中动态变化的元素,这样链式调用和写SQL语句的思维顺序是一致的,只不过我们之前通过硬编码的方式变成了方法调用。,具体代码如下:,外部使用起来效果:,顾名思义Scanner的作用就是把查询结果设置到对应的go对象上去,完成关系和对象的映射,关键核心就是通过反射获知传入对象的类型和字段类型,通过反射创建对象和值,并通过golang结构体的字段后面的tag来和查询结果的表头一一对应,达到动态给结构字段赋值的能力。,图片,具体实现如下:,通过反射赋值流程,如果想知道具体的实现细节可以仔细阅读上面代码里面的注释,图片,有了SQLBuilder和Scanner 我们就可以这样写查询函数了:,生成的查询SQL语句和args如下:,自动生成,通过上面的使用的例子来看,我们的工作轻松了不少:,着实帮我们省了很大的麻烦。但是查询字段还需要我们自己手写,像这种,Table对象如下:,使用以上Table对象的模板代码:,通过上面的模板我们用user表的建表SQL语句生成如下代码:,那么我们在查询的时候就可以这样使用,通过模板自动生成代码,可以大大的减轻开发编码负担,使我们从繁重的代码中解放出来。,reflect真的有必要吗?,由于我们SELECT时选择查找的字段和顺序是不固定的,我们有可能 SELECT id, name, age FROM user,也可能 SELECT name, id FROM user,有很大的任意性,这种情况使用反射出来的结构体tag和查询的列名来确定映射关系是必须的。但是有一种情况我们不需要用到反射,而且是一种最常用的情况,即:查询的字段名和表结构的列名一致,且顺序一致。这时候我们可以这么写,通过DeepEqual来判断查询字段和表结构字段是否一致且顺序一致来决定是否通过反射还是通过传统方法来创建对象。用传统方式创建对象(如下图第12行)令我们编码痛苦,不过可以通过模板来自动生成下面的代码,以避免手写,这样既灵活方便好用,性能又没有损耗,看起来是一个比较完美的解决方案。,总结,通过表结构,我们可以生成对应的结构体和持久层增删改查代码,我们再往前扩展一步,能否通过表结构生成的proto格式的message,以及一些常用的CRUD GRPC rpc接口定义。通过工具,我们甚至可以把前端的代码都生成好,实现半自动化编程。我想这个是值得期待的。,参考资料:[1] ​​https://github.com/ent/ent​​,​本期作者:洪胜杰,B端技术中心高级开发工程师​,图片,
,
,

文章版权声明

 1 原创文章作者:cmcc,如若转载,请注明出处: https://www.52hwl.com/21981.html

 2 温馨提示:软件侵权请联系469472785#qq.com(三天内删除相关链接)资源失效请留言反馈

 3 下载提示:如遇蓝奏云无法访问,请修改lanzous(把s修改成x)

 免责声明:本站为个人博客,所有软件信息均来自网络 修改版软件,加群广告提示为修改者自留,非本站信息,注意鉴别

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2023年3月5日 上午12:00
下一篇 2023年3月7日 下午10:34