golang封装mysql涉及到的包以及sqlx和gorm的区别

一、前言

      本篇是搬运之前的笔记,刚用golang的时候,看到mysql的封装部分,总是很好奇为什么会用到那么多的包,例如:

"database/sql"
"github.com/go-sql-driver/mysql"
"github.com/jmoiron/sqlx"
"github.com/jmoiron/sqlx/reflectx"
"vitess.io/vitess/go/vt/sqlparser"
"github.com/Masterminds/squirrel"
"github.com/lann/builder"

这些包之间都有什么区别呢?到底哪些才是我们封装mysql需要用到的关键包?

二、解析各种包

参考:Go语言标准库学习之database/sql——数据库管理的利器

1、database/sql

      sql包是go官方提供的操作mysql的扩展,主要是提供了操作mysql的方法,比如增删改查,事务等功能。

sql操作的主要方式依赖于原生的sql编写,例如:

db.Query("SELECT * FROM student")

2、go-sql-driver/mysql"

      这个包也是go官方提供的mysql驱动包。连接mysql的步骤如下:

1.导入数据库引擎,也就是导入mysql驱动
2.连接数据库: root:password@tcp(host:port)/database?charset=utf8&parseTime=True&loc=Local
3.设置相关参数
4.测试连接

      此处的驱动包,主要就是导入mysql驱动,让我们的sql包可以连接到数据库,主要用法如下:

_ "github.com/go-sql-driver/mysql"
db, err := sql.Open("mysql",config)  //第一个参数mysql就是用法哦

      使用“_”操作引用包是无法通过包名来调用包中的导出函数,而是只是为了简单的调用其init()函数。导入数据库引擎之后,就可以通过sql包的sql.open()方法连接数据库。

3、sqlx包

参考:
sqlx文档
sqlx使用说明

      sqlxGo 的一个包,它在优秀的内置database/sql包之上提供了一组扩展。也就是说。sqlx也是个操作mysql的标准库。

既然sql包已经是官方出的了,那么为什么大家反而更喜欢用sqlx包呢?

(1)安全性
  database/sql 不会尝试对查询文本进行任何验证;它与编码参数一起按原样发送到服务器。
  而sqlx提供了专门的参数绑定方法sqlx.DB.Rebind(string) string,支持mysql问号(?)
  或命名的Prepared Statements,避免SQL注入的安全问题
  
(2)便利
  相对于原生sql包的query,sqlx.Rowx的主要扩展就是StructScan,可以自动把查下结果扫描
  到对应结构体中的域(fileld)中。把SQL执行的结果集转化成数据结构(Struct、Maps、Slices)。
  
(3)sqlx的get和select方法

  Get和Select是一个非常省时的扩展。它们把query和非常灵活的scan语法结合起来。
  Get和Select在执行查询后就会关闭Rows,并且在执行阶段遇到任何问题都会返回错误。
  缺点:Select会把整个结果一次放入内存。如果查询结果没有限制特定的大小,那么最好使用Query/StructScan迭代方法。

sqlx包的sql操作方式,也是依赖于原生的sql编写:

db.Query("SELECT * FROM student")

4、reflectx包

sqlx 包有特殊的反射需求。特别是,它需要:

能够将名称映射到字段
了解嵌入式结构
了解通过特定标签将名称映射到字段
用户指定名称 -> 字段映射函数

reflectx包主要扩展了原reflect包,以实现上述目的。

5、squirrel 包 和 Builder包

      这两个包主要作用是sql生成器,实现查询构建,用于链式调用。我们知道原生的sql包都是需要自己来手动编写sql的,而程序员是喜欢懒一点,最好是输入首字母就可以自动补全,点点点的链式调用一路莽到底。

(1)sqlx + squirrel 实现

squirrel是go的sql生成器,类似于之前用过的查询构造器,可以实现链式调用,如:
sql, args, err := sq.
Insert("users").Columns("name", "age").
Values("moe", 13).Values("larry", sq.Expr("? + 5", 12)).
ToSql()

(2)builder 包

Builder 最初是为 Squirrel编写的,它是一个流畅的 SQL 生成器。这可能是 Builder 的最佳示例。
Builder通过方法链帮助您为您的库编写流畅的 DSL

6、vitess.io/vitess/go/vt/sqlparser包

注意:这个地址现在已经404了

(1) vitess-sqlparser
  vitess-sqlparser 仅仅是Go语言SQL和DDL解析器(由vitess和TiDB支持)
(2)vitess
   参考:https://blog.51cto.com/u_15080030/2642755
  Vitess是一个用于部署、扩展和管理大型mysql实例集群的数据库解决方案。

      以上了解了常见的mysql相关的包,怪不得大佬们封装mysql的时候都需要引入这么多的包,环环相扣,从安全性到链式调用,组合封装起来让大家用起来更省劲。

三、sqlx和gorm

1.gorm包

参考:Gorm官方文档

GORM是GoLang中最出色的ORM框架,支持MySQL、PostgreSQL、Sqlite、SQL Server,功能非常
强大,也可以直接执行SQL并获取结果集。主要操作方式是orm的形式,相对于sql扩展包来说,
orm是又进行了更深层次的封装,对于简单sql,使用orm是可以有效提升效率的。

orm是object Relational Mapping缩写,object是对象,relational是关系,mapping是映射。
对象关系映射看起来还是蛮抽象的,没错,它就是个抽象概念。从编程语法上来看,
就是在具体的操作业务对象的时候,不需要再去和复杂的SQL语句打交道,只需简单的
操作对象的属性和方法。

gorm也是类似于其他语言的ORM方式操作数据库,更加偏向于一切皆对象。

2、gorm和sqlx的对比

(1)sqlx是一个库,它允许您将整行扫描到您的结构变量中。虽然sqlx减少了为构建 CRUD 而编写的典型行数,但最终仍会多次编写重复代码。
使用 ORM 可以帮助减少它并专注于您的业务逻辑。
(2)针对复杂的sq,比如编写报表的子查询,多表关联操作,orm实现起来可能更加的复杂,使用原生sql反而更好。
(3)效率上
    参考:https://tech.wmzhe.com/article/97958.html ,显然sqlx效率更高
(4)orm是一个与表映射的类,字段映射成成员变量。当表字段很多的时候,orm类就会很冗长。

      其实不管是sqlx还是gorm,对于我们日常的开发来说都是足够使用的,博主呆过的几家公司还是以sqlx为主,ORM虽然方便,但是更加抽象化一点,可能大家觉得sqlx更加容易上手吧。

      博主觉得,重要的不是用sqlx还是用gorm重要的是统一标准以及sql层的封装。统一标准是为了代码的可读性和可维护性,sql层封装又是为了防止代码冗余和便于插入洋葱模型中间件,实现服务稳定性的相关指标。

3、封装sql关注的点有哪些

(1)读取中心配置,连接mysql,比如apollo等
(2)添加洋葱模型,例如添加trace,spanID,requestId等分布式链路追踪到context,
添加log打印关键日志

end

猜你喜欢

转载自blog.csdn.net/LJFPHP/article/details/125983972