gorm学习系列之一:gorm.Open函数详解

yudotyang · · 1945 次点击 · · 开始浏览    
这是一个创建于 的文章,其中的信息可能已经有所发展或是发生改变。

大家好,我是渔夫子。 所以本系列文章意在深入的学习gorm,以便更好的理解和使用gorm,而不是简单的使用增、删、改、查功能。 > 关注 [Go学堂](https://goxuetang.github.io) ,提前获取更多gorm系列文章 ## 什么是gorm gorm是用于golang编程的非常优秀的ORM库,可使开发者对数据库使用更为方便。该库不仅支持多种数据库。而且还提供了查询构建器、关系映射、事务等多种功能。 ## 初始化数据库连接:gorm.Open 要针对数据库进行操作,第一步就是要创建一个和数据库的连接。在gorm中使用的就是`gorm.Open`函数。接下来就们就看一下gorm.Open都做了些什么事儿。 假设我们要连接一个mysql数据库,像如下代码这样就能建立数据的连接: ```go import ( "gorm.io/driver/mysql" "gorm.io/gorm" ) func main() { // refer https://github.com/go-sql-driver/mysql#dsn-data-source-name for details dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local" db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{}) } ``` 我们看到上面的代码还依赖了mysql的驱动库:`gorm.io/driver/mysql`,该库是mysql的驱动库。这个就是要告诉gorm要连接的具体数据库了。 在go-gorm项目下还能找到`sqlite`、`sqlserver`、`postgres`以及`clickhouse`等常用的数据库的驱动库。地址是:[https://github.com/go-gorm](https://github.com/go-gorm)目录下。 我们再看下gorm.Open的函数原型: ```go func Open(dialector Dialector, opts ...Option) (db *DB, err error) ``` 第一个参数是Dialector接口。该接口定义如下: ```go type Dialector interface { Name() string Initialize(*DB) error Migrator(db *DB) Migrator DataTypeOf(*schema.Field) string DefaultValueOf(*schema.Field) clause.Expression BindVarTo(writer clause.Writer, stmt *Statement, v interface{}) QuoteTo(clause.Writer, string) Explain(sql string, vars ...interface{}) string } ``` 看到这里就明白了,只要具体的数据库驱动实现了该接口,gorm就能支持该数据库的连接。也就是说上面我们提到的go-gorm目录下的各种具体的数据库驱动都实现了Dialector接口。 ### dsn是什么 dsn,即data source name,指的是数据源名称。在golang中,其格式如下: ```go [user[:password]@][net[(addr)]]/dbname[?param1=value1&paramN=valueN] ``` ### mysql.Open函数 mysql.Open函数的返回值是gorm.Dialector对象。也就是说这里只是把相关的配置赋值给了gorm.Dialector接口类型,并没有实际的和数据库建立连接。如下是mysql.Open函数的实现: ```go func Open(dsn string) gorm.Dialector { dsnConf, _ := mysql.ParseDSN(dsn) return &Dialector{Config: &Config{DSN: dsn, DSNConfig: dsnConf}} } ``` 当然,其他数据库的Open函数也是类似,比如clickhouse数据库的Open函数实现如下: ```go func Open(dsn string) gorm.Dialector { return &Dialector{Config: &Config{DSN: dsn}} } ``` ### 建立数据库连接:Dialector.Initialize 在gorm.Open函数中,是通过Dialector.Initialize函数和数据库建立实际连接的。如下: ``` if config.Dialector != nil { err = config.Dialector.Initialize(db) } ``` Dialector就是上文中提到的通过各个具体的数据库驱动的Open函数返回的接口类型。实际上也就是自己驱动下Dialector对象。然后在执行各自实例的Initialize函数,就能通过dsn中配置的地址和账号建立数据库连接了。 ![image (6).png](https://static.golangjob.cn/231120/25dcb510c21cffaa6c31a0763096590c.png) 我们还是以mysql数据库为例,我们看下Initialize函数的核心实现: ![image (5).png](https://static.golangjob.cn/231120/6b5e773f6085642c6537aacf22a95ee3.png) 本质上,在创建数据库连接的时候还是基于golang标准库的database/sql库实现的。最终,通过gorm.Open函数就初始化了一个数据库的连接 ### 核心数据结构 上文提到,通过gorm.Open函数会得到一个gorm.DB对象。该对象是gorm中的核心数据结构。如下是gorm.DB的结构体: 在gorm.DB结构中主要包含两个类型的字段:Config和Statement。 Config结构体根据名字可知主要是一些和数据库相关的配置,比如和账号密码以及连接地址相关的Dailector、数据库的连接ConnPool,日志相关的等。 Statement结构体,我们看到该结构体的主要由Table、Model、Select、Schema等组成,可想而知是跟具体的sql语句有关系的。 ## 总结 通过gorm建立数据库连接的时候,要依赖于具体连接哪种数据库,所以gorm项目下提供了多种数据库的驱动。这些数据库驱动遵守gorm提供的接口类型Dailector来创建连接。实际创建连接的函数是Initialize函数,并将创建好的连接返回给gorm.DB.ConnPool字段中。 **特别说明:**你的关注,是我写下去的最大动力。点击下方公众号卡片,直接关注。关注送《100个go常见的错误》pdf文档、经典go学习资料。

有疑问加站长微信联系(非本文作者))

入群交流(和以上内容无关):加入Go大咖交流群,或添加微信:liuxiaoyan-s 备注:入群;或加QQ群:692541889

1945 次点击  
加入收藏 微博
暂无回复
添加一条新回复 (您需要 登录 后才能回复 没有账号 ?)
  • 请尽量让自己的回复能够对别人有帮助
  • 支持 Markdown 格式, **粗体**、~~删除线~~、`单行代码`
  • 支持 @ 本站用户;支持表情(输入 : 提示),见 Emoji cheat sheet
  • 图片支持拖拽、截图粘贴等方式上传