本篇是搬运之前的笔记,刚用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——数据库管理的利器
sql
包是go
官方提供的操作mysql
的扩展,主要是提供了操作mysql
的方法,比如增删改查,事务等功能。
sql
操作的主要方式依赖于原生的sql
编写,例如:
db.Query("SELECT * FROM student")
这个包也是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()
方法连接数据库。
参考:
sqlx文档
sqlx使用说明
sqlx
是 Go
的一个包,它在优秀的内置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")
sqlx
包有特殊的反射需求。特别是,它需要:
能够将名称映射到字段
了解嵌入式结构
了解通过特定标签将名称映射到字段
用户指定名称 -> 字段映射函数
reflectx
包主要扩展了原reflect
包,以实现上述目的。
这两个包主要作用是sql
生成器,实现查询构建,用于链式调用。我们知道原生的sql
包都是需要自己来手动编写sql
的,而程序员是喜欢懒一点,最好是输入首字母就可以自动补全,点点点的链式调用一路莽到底。
squirrel是go的sql生成器,类似于之前用过的查询构造器,可以实现链式调用,如:
sql, args, err := sq.
Insert("users").Columns("name", "age").
Values("moe", 13).Values("larry", sq.Expr("? + 5", 12)).
ToSql()
Builder 最初是为 Squirrel编写的,它是一个流畅的 SQL 生成器。这可能是 Builder 的最佳示例。
Builder通过方法链帮助您为您的库编写流畅的 DSL
注意:这个地址现在已经404了
(1) vitess-sqlparser
vitess-sqlparser 仅仅是Go语言SQL和DDL解析器(由vitess和TiDB支持)
(2)vitess
参考:https://blog.51cto.com/u_15080030/2642755
Vitess是一个用于部署、扩展和管理大型mysql实例集群的数据库解决方案。
以上了解了常见的mysql
相关的包,怪不得大佬们封装mysql
的时候都需要引入这么多的包,环环相扣,从安全性到链式调用,组合封装起来让大家用起来更省劲。
参考: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
方式操作数据库,更加偏向于一切皆对象。
(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
层封装又是为了防止代码冗余和便于插入洋葱模型中间件,实现服务稳定性的相关指标。
(1)读取中心配置,连接mysql,比如apollo等
(2)添加洋葱模型,例如添加trace,spanID,requestId等分布式链路追踪到context,
添加log打印关键日志
end