文章首发于公众号【程序员读书】,欢迎关注。
这是《Golang GORM实战》系列的第二篇,在这篇文章中我们来了解一下GORM是如何连接不同类型的数据库,以及如何配置连接时的参数。
连接数据库
使用GORM连接数据库还是比较简单的,概括起来就是以下三个步骤:
引入gorm.io/gorm
和对应数据库的驱动库,如gorm.io/driver/sqlite
。
调用对应驱动库的Open()或New()函数返回一个实现了gorm.Dialector接口的实例。
调用gorm.Open()方法传入一个gorm.Dialector接口的实例以初始一个gorm.DB对象。
通过上述三个步骤,最终获取一个gorm.DB对象,我们便可以使用该对象的方法操作数据库,如Create,Delete等方法。
下面我们来看MySQL,PostgreSQL,SQLite,SQL Server等不同数据库是怎么执行上述几个步骤连接数据库的:
MySQL
简单连接
下面是连接mysql数据库最简单的方式,我们只需要定义好dsn便可以了,如下:
import("gorm.io/driver/mysql""gorm.io/gorm")funcmain(){dsn:="user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db,err:=gorm.Open(mysql.Open(dsn))}
mysql.New
如果我们在连接数据库时,想进一步配置,则可以使用mysql.New()函数,该函数可以传递一个mysql.Config进行详细配置,如:
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))
如果我们查看mysql.Config,可以更加了解在连接数据库时,还可以配置哪些参数,mysql.Config的源码如下:
typeConfigstruct{DriverNamestringDSNstringConngorm.ConnPoolSkipInitializeWithVersionboolDefaultStringSizeuintDefaultDatetimePrecision*intDisableDatetimePrecisionboolDontSupportRenameIndexboolDontSupportRenameColumnboolDontSupportForShareClausebool}
通过sql.DB初始化*gorm.DB
如果我们自己使用database/sql打开一个数据库连接,那么也可以利用这个已经存在的连接,来初始化一个gorm.DB对象, 如:
packagemainimport("database/sql""gorm.io/driver/mysql""gorm.io/gorm")funcmain(){db,_:=sql.Open("mysql","root:123456@tcp(localhost:3306)/test?charset=utf8&parseTime=True&loc=Local")db,err:=gorm.Open(mysql.New(mysql.Config{Conn:db,}))}
PostgreSQL
简单连接
import("gorm.io/driver/postgres"//驱动库"gorm.io/gorm")dsn:="host=localhostuser=gormpassword=gormdbname=gormport=9920sslmode=disableTimeZone=Asia/Shanghai"db,err:=gorm.Open(postgres.Open(dsn))
postgres.New
packagemainimport("gorm.io/driver/postgres""gorm.io/gorm")funcmain(){dsn:="host=localhostuser=gormpassword=gormdbname=gormport=9920sslmode=disableTimeZone=Asia/Shanghai"db,err:=gorm.Open(postgres.New(postgres.Config{DSN:dsn,PreferSimpleProtocol:true,}))}
通过sql.DB初始化*gorm.DB
packagemainimport("database/sql""gorm.io/driver/postgres""gorm.io/gorm")funcmain(){dsn:="host=localhostuser=gormpassword=gormdbname=gormport=9920sslmode=disableTimeZone=Asia/Shanghai"sqlDB,_:=sql.Open("pgx",dsn)db,err:=gorm.Open(postgres.New(postgres.Config{Conn:sqlDB,PreferSimpleProtocol:true,}))}
SQL Server
简单连接
import("gorm.io/driver/sqlserver""gorm.io/gorm")dsn:="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"db,err:=gorm.Open(sqlserver.Open(dsn))
sqlserver.New
packagemainimport("gorm.io/driver/sqlserver""gorm.io/gorm")funcmain(){dsn:="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"db,err:=gorm.Open(sqlserver.New(sqlserver.Config{DSN:dsn,}))}
通过sql.DB初始化*gorm.DB
packagemainimport("database/sql""gorm.io/driver/sqlserver""gorm.io/gorm")funcmain(){dsn:="sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"sqlDB,_:=sql.Open("sqlserver",dsn)db,err:=gorm.Open(sqlserver.New(sqlserver.Config{Conn:sqlDB,}))}
SQLite
因为SQLite数据库其实只是一个文件而已,所以SQLite的连接非常简单,只需要传入SQLite数据库的文件路径即可,比如我们连接一个在当前目录的gorm.db数据,其连接方式如下:
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))0
另外,连接SQLite数据库时,也可以在内存中创建临时数据库,而需要一个实际的数据库,其连接方式如下所示:
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))1
gorm.Config
在上面的示例中,我们都用gorm.Open()打开数据库连接的,我们查看这个方法的源码,如:
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))2
我们可以看到其实第一个参数外,后面还可以无限传入类型为Option的参数,用于配置连接参数,而Option是一个接口,如下:
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))3
gorm.Config实现了Option接口,因此我们可以将gorm.Config传递给gorm.Open函数,gorm.Config的源码
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))4
下面是使用gorm.Config的参数来控制数据库连接的示例,如:
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))5
连接池
通过数据库连接池,我们可以避免频繁创建和销数据库连接所带来的开销,GROM的数据连接池底层是通过database/sql来实现的,所以其设置方法与database/sql
是一样的。
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))6
关闭数据库
程序执行结束后,需要关闭数据连接,而GORM的底层仍然是通过database/sql去连接数据库的,因此要通过gorm.DB对象的DB()方法返回的sql.DB
来关闭数据库连接,如:
dsn:="root:123456@tcp(127.0.0.1:3306)/test?charset=utf8mb4&parseTime=true&loc=UTC"db,err:=gorm.Open(mysql.New(mysql.Config{DSN:dsn,//DSNdatasourcenameDefaultStringSize:256,//string类型字段的默认长度DisableDatetimePrecision:true,//禁用datetime精度,MySQL5.6之前的数据库不支持DontSupportRenameIndex:true,//重命名索引时采用删除并新建的方式,MySQL5.7之前的数据库和MariaDB不支持重命名索引DontSupportRenameColumn:true,//用`change`重命名列,MySQL8之前的数据库和MariaDB不支持重命名列SkipInitializeWithVersion:false,//根据当前MySQL版本自动配置}))7
小结
在这篇文章,我们学习了使用GORM去连接MySQL,PostgreSQL,SQLServer,SQLite等不同数据库的方式,可以看出连接不同的数据的方式大同小异,只是配置(Config)有些许不同,相信你应该已经掌握了吧!