本教程介绍了使用 Godatabase/sql及其标准库中的包访问关系数据库的基础知识。
通许网站建设公司创新互联,通许网站设计制作,有大型网站制作公司丰富经验。已为通许上千提供企业网站建设服务。企业网站搭建\外贸营销网站建设要多少钱,请找那个售后服务好的通许做网站的公司定做!
您将使用的database/sql包包括用于连接数据库、执行事务、取消正在进行的操作等的类型和函数。
在本教程中,您将创建一个数据库,然后编写代码来访问该数据库。您的示例项目将是有关老式爵士乐唱片的数据存储库。
首先,为您要编写的代码创建一个文件夹。
1、打开命令提示符并切换到您的主目录。
在 Linux 或 Mac 上:
在 Windows 上:
2、在命令提示符下,为您的代码创建一个名为 data-access 的目录。
3、创建一个模块,您可以在其中管理将在本教程中添加的依赖项。
运行go mod init命令,为其提供新代码的模块路径。
此命令创建一个 go.mod 文件,您添加的依赖项将在其中列出以供跟踪。
注意: 在实际开发中,您会指定一个更符合您自己需求的模块路径。有关更多信息,请参阅一下文章。
GO语言(二十五):管理依赖项(上)
GO语言(二十六):管理依赖项(中)
GO语言(二十七):管理依赖项(下)
接下来,您将创建一个数据库。
在此步骤中,您将创建要使用的数据库。您将使用 DBMS 本身的 CLI 创建数据库和表,以及添加数据。
您将创建一个数据库,其中包含有关黑胶唱片上的老式爵士乐录音的数据。
这里的代码使用MySQL CLI,但大多数 DBMS 都有自己的 CLI,具有类似的功能。
1、打开一个新的命令提示符。
在命令行,登录到您的 DBMS,如下面的 MySQL 示例所示。
2、在mysql命令提示符下,创建一个数据库。
3、切到您刚刚创建的数据库,以便您可以添加表。
4、在文本编辑器的 data-access 文件夹中,创建一个名为 create-tables.sql 的文件来保存用于添加表的 SQL 脚本。
将以下 SQL 代码粘贴到文件中,然后保存文件。
在此 SQL 代码中:
(1)删除名为album表。 首先执行此命令可以让您更轻松地稍后重新运行脚本。
(2)创建一个album包含四列的表:title、artist和price。每行的id值由 DBMS 自动创建。
(3)添加带有值的四行。
5、在mysql命令提示符下,运行您刚刚创建的脚本。
您将使用以下形式的source命令:
6、在 DBMS 命令提示符处,使用SELECT语句来验证您是否已成功创建包含数据的表。
接下来,您将编写一些 Go 代码进行连接,以便进行查询。
现在你已经有了一个包含一些数据的数据库,开始你的 Go 代码。
找到并导入一个数据库驱动程序,该驱动程序会将您通过database/sql包中的函数发出的请求转换为数据库可以理解的请求。
1、在您的浏览器中,访问SQLDrivers wiki 页面以识别您可以使用的驱动程序。
2、使用页面上的列表来识别您将使用的驱动程序。为了在本教程中访问 MySQL,您将使用 Go-MySQL-Driver。
3、请注意驱动程序的包名称 - 此处为github.com/go-sql-driver/mysql.
4、使用您的文本编辑器,创建一个用于编写 Go 代码的文件,并将该文件作为 main.go 保存在您之前创建的数据访问目录中。
5、进入main.go,粘贴以下代码导入驱动包。
在此代码中:
(1)将您的代码添加到main包中,以便您可以独立执行它。
(2)导入 MySQL 驱动程序github.com/go-sql-driver/mysql。
导入驱动程序后,您将开始编写代码以访问数据库。
现在编写一些 Go 代码,让您使用数据库句柄访问数据库。
您将使用指向结构的指针sql.DB,它表示对特定数据库的访问。
编写代码
1、进入 main.go,在import您刚刚添加的代码下方,粘贴以下 Go 代码以创建数据库句柄。
在此代码中:
(3)使用 MySQL 驱动程序Config和FormatDSN类型以收集连接属性并将它们格式化为连接字符串的 DSN。
该Config结构使代码比连接字符串更容易阅读。
(4)调用sql.Open 初始化db变量,传递 FormatDSN。
(5)检查来自 的错误sql.Open。例如,如果您的数据库连接细节格式不正确,它可能会失败。
为了简化代码,您调用log.Fatal结束执行并将错误打印到控制台。在生产代码中,您会希望以更优雅的方式处理错误。
(6)调用DB.Ping以确认连接到数据库有效。在运行时, sql.Open可能不会立即连接,具体取决于驱动程序。您在Ping此处使用以确认 database/sql包可以在需要时连接。
(7)检查来自Ping的错误,以防连接失败。
(8)Ping如果连接成功,则打印一条消息。
文件的顶部现在应该如下所示:
3、保存 main.go。
1、开始跟踪 MySQL 驱动程序模块作为依赖项。
使用go get 添加 github.com/go-sql-driver/mysql 模块作为您自己模块的依赖项。使用点参数表示“获取当前目录中代码的依赖项”。
2、在命令提示符下,设置Go 程序使用的DBUSER和DBPASS环境变量。
在 Linux 或 Mac 上:
在 Windows 上:
3、在包含 main.go 的目录中的命令行中,通过键入go run来运行代码。
连接成功了!
接下来,您将查询一些数据。
golang在1.6.2的时候还没有自己的context,在1.7的版本中就把golang.org/x/net/context包被加入到了官方的库中。中文译作“上下文”,它主要包含了goroutine 的运行状态、环境等信息。
context 主要用来在 goroutine 之间传递上下文信息,包括:同步信号、超时时间、截止时间、请求相关值等。
该接口定义了四个需要实现的方法:
如果有个网络请求Request,然后这个请求又可以开启多个goroutine做一些事情,当这个网络请求出现异常和超时时,这个请求结束了,这时候就可以通过context来跟踪这些goroutine,并且通过Context来取消他们,然后系统才可回收所占用的资源。
为了更方便的创建Context,包里头定义了Background来作为所有Context的根,它是一个emptyCtx的实例。
Background返回一个非空的Context。它永远不会被取消。它通常用来初始化和测试使用,作为一个顶层的context,也就是说一般我们创建的context都是基于Background。
TODO返回一个非空的Context。当不清楚要使用哪个上下文的时候可以使用TODO。
他们两个本质上都是emptyCtx结构体类型,是一个不可取消,没有设置截止时间,没有携带任何值的Context。
有了如上的根Context,那么是如何衍生更多的子Context的呢?这就要靠context包为我们提供的With系列的函数了。
通过这些函数,就创建了一颗Context树,树的每个节点都可以有任意多个子节点,节点层级可以有任意多个。
WithCancel函数,最常用的派生 context 方法。该方法接受一个父 context。父 context 可以是一个 background context 或其他 context。
WithDeadline函数,该方法会创建一个带有 deadline 的 context。当 deadline 到期后,该 context 以及该 context 的可能子 context 会受到 cancel 通知。另外,如果 deadline 前调用 cancelFunc 则会提前发送取消通知。
WithTimeout和WithDeadline基本上一样,这个表示是超时自动取消,是多少时间后自动取消Context的意思。
WithValue函数和取消Context无关,它是为了生成一个绑定了一个键值对数据的Context,这个绑定的数据可以通过Context.Value方法访问到,一般我们想要通过上下文来传递数据时,可以通过这个方法,如我们需要tarce追踪系统调用栈的时候。
使用Context的程序应遵循以下规则,以使各个包之间的接口保持一致:
1.不要将 Context 塞到结构体里。直接将 Context 类型作为函数的第一参数,而且一般都命名为 ctx。
2.不要向函数传入一个 nil 的 context,如果你实在不知道传什么,标准库给你准备好了一个 context:todo。
3.不要把本应该作为函数参数的类型塞到 context 中,context 存储的应该是一些共同的数据。例如:登陆的 session、cookie 等。
4.同一个 context 可能会被传递到多个 goroutine,别担心,context 是并发安全的。
eBay早在2002年的时候,就开发了一套叫做CAL(Centralized Application Logging)的链路追踪系统,在eBay内部堪称架构神器。不过没有开源。
Google在与eBay差不多的时间,也开发了一套链路追踪系统,叫Dapper,在Google内部运行了很长时间,一直没有开源。不过在2010年的时候,Google发布了一篇划时代的论文,来介绍Dapper的原理。Dapper论文成了后面众多链路追踪系统的理论基础。
下面是Dapper论文的英文原版和中文翻译版:
Dapper 英文版
Dapper 中文翻译版
在eBay工作了十多年的 吴其敏 加入大众点评成为首席架构师。吴其敏以eBay的CAL为模板,在2011年底,开始研发名为 CAT (Central Application Tracking)的链路追踪系统。CAT在2014年开始开源,已经被众多知名公司使用。
下面是美团官方技术博客对CAT的介绍:
美团官方技术博客 - 深度剖析开源分布式监控CAT
下面是CAT Github地址:
CAT - Github
下面是CAT UI示例:
Twitter在2012年开源了Zipkin。不过Zipkin最早是用scala实现的,比较小众。后来由社区用java重写为OpenZipkin,才开始流行起来。Zipkin可以认为是Dapper论文的工程实践。
下面是Zipkin的官网和Github地址:
Zipkin官网
Zipkin - Github
下面是Zipkin Tracing UI示例:
Pinpoint是一家名叫Naver的韩国公司的产品。Naver是韩国当前最大的互联网服务公司。Pinpoint的创新点在于使用了字节码注入技术,埋点是无侵入的。
下面是Pinpoint在Github的地址:
Pinpoint - Github
下面是Pinpoint Tracing UI示例:
2015年,前OneAPM成员 吴晟 借鉴Pinpoint的思想,开发并开源了Skywalking,并在2017年时进入Apache孵化器。在Apache背书的情况下,Skywalking近几年在国内发展迅速。
同Pinpoint一样,Skywalking也使用了字节码注入技术,埋点也是无侵入的。
下面是Skywalking Github地址:
Github - Skywalking
下面是Skywalking一个体验版服务:
Skywalking - Demo
下面是Skywalking Tracing UI示例:
2016年,Uber受Dapper和OpenZipkin启发,用Go语言开发了链路追踪系统Jaeger。可以认为Jaeger是Zipkin的golang版。
下面是Jaeger官网和Github地址:
Jaeger官网
Github - Jaeger
下面是Jaeger Tracing UI示例:
CAT可以说是与CAL同根同源。而Zipkin、Pinpoint、Skywalking、Jaeger均是参考Dapper论文发展而来,因此,上述产品可大致按下图划分:
另外,链路追踪和APM可以说是密不可分,也越来越多的开源产品不仅局限于提供Tacing的功能。上述开源产品中,有很多产品本质上是个APM,Tracing只是其众多功能中的一部分:
后续会对比上述几个开源产品的异同,做为在技术选型时作为参考。