连接数据库
使用GORM连接数据库还是比较简单的,概括起来就是以下三个步骤:
-
引入
gorm.io/gorm
和对应数据库的驱动库,如gorm.io/driver/sqlite
。 -
调用对应驱动库的Open()或New()函数返回一个实现了gorm.Dialector接口的实例。
-
调用gorm.Open()方法传入一个gorm.Dialector接口的实例以初始一个gorm.DB对象。
通过上述三个步骤,最终获取一个gorm.DB对象,我们便可以使用该对象的方法操作数据库,如Create,Delete等方法。
MySQL
简单连接
下面是连接mysql数据库最简单的方式,我们只需要定义好dsn便可以了
package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)var DB *gorm.DBfunc main() {//user、password、IP、port、dbnamedsn := "user:password@tcp(ip:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{SkipDefaultTransaction: false, //设置为 false 表示不跳过默认事务NamingStrategy: nil, //设置为 nil,表示使用 GORM 的默认命名策略FullSaveAssociations: false, //设置为 false 表示不完整保存关联的记录Logger: nil, //设置为 nil,表示不设置自定义的日志记录器NowFunc: nil, //设置为 nil,表示使用 GORM 的默认时间函数DryRun: false, //设置为 false,表示不执行模拟运行PrepareStmt: false, //设置为 false,表示不预先准备语句DisableAutomaticPing: false, //设置为 false,表示不禁用自动心跳检测DisableForeignKeyConstraintWhenMigrating: false, //设置为 false,表示在迁移时不禁用外键约束IgnoreRelationshipsWhenMigrating: false, //设置为 false,表示在迁移时不忽略关系DisableNestedTransaction: false, //设置为 false,表示不禁用嵌套事务AllowGlobalUpdate: false, //设置为 false,表示不允许全局更新QueryFields: false, //设置为 false,表示不使用字段查询CreateBatchSize: 0, //设置为 0,表示使用 GORM 的默认批量创建大小TranslateError: false, //设置为 false,表示不转换错误ClauseBuilders: nil, //设置为 nil,表示不设置自定义的查询子句构建器ConnPool: nil, //设置为 nil,表示使用 GORM 的默认连接池Dialector: nil, //设置为 nil,表示使用 GORM 的默认方言(dialect)Plugins: nil, //设置为 nil,表示不使用任何插件})if err != nil {panic("数据库连接错误")}DB = db
}
mysql.New
如果我们在连接数据库时,想进一步配置,则可以使用mysql.New()函数,该函数可以传递一个mysql.Config进行详细配置,如:
package mainimport ("gorm.io/driver/mysql""gorm.io/gorm"
)var DB *gorm.DBfunc main() {//user、password、IP、port、dbnamedsn := "user:password@tcp(ip:port)/dbname?charset=utf8mb4&parseTime=True&loc=Local"//db, err := gorm.Open(mysql.New(mysql.Config{// DSN: dsn, // DSN data source name// DefaultStringSize: 256, // string 类型字段的默认长度// DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持// DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引// DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列// SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置//}))db, err := gorm.Open(mysql.New(mysql.Config{DriverName: dsn, //驱动程序的名称,通常不需要手动设置,GORM 默认使用 mysqlServerVersion: "", //服务器版本,通常在连接成功后由 GORM 自动设置DSN: "", //数据源名称,这是一个包含数据库连接信息的字符串,格式通常为 username:password@tcp(address:port)/dbname?param=valueDSNConfig: nil, //一个 mysql.DSNConfig 类型的配置,用于进一步配置 DSN 字符串Conn: nil, //一个原始的连接对象,通常不需要手动设置SkipInitializeWithVersion: false, //设置为 false 表示不跳过使用服务器版本进行初始化DefaultStringSize: 0, //默认的字符串大小,设置为 0 表示使用 GORM 的默认值DefaultDatetimePrecision: nil, //默认的 datetime 精度,这里设置为 nil,表示使用 GORM 的默认值DisableWithReturning: false, //设置为 false 表示不禁用 WITH RETURNING 支持DisableDatetimePrecision: false, //设置为 false 表示不禁用 datetime 精度支持DontSupportRenameIndex: false, //以 DontSupport 开头的字段:这些字段表示是否不支持某些特定的数据库功能,这里全部设置为 false,表示没有禁用任何功能DontSupportRenameColumn: false, //DontSupportForShareClause: false, //DontSupportNullAsDefaultValue: false, //DontSupportRenameColumnUnique: false, //DontSupportDropConstraint: false, //}))if err != nil {panic("数据库连接错误")}DB = db
}
通过sql.DB初始化*gorm.DB
如果我们自己使用database/sql打开一个数据库连接,那么也可以利用这个已经存在的连接,来初始化一个gorm.DB对象, 如:
package mainimport ("database/sql""gorm.io/driver/mysql""gorm.io/gorm"
)var DB *gorm.DBfunc main() {db, err := sql.Open("mysql", "root:123qwe@tcp(localhost:3306)/mysql_db?charset=utf8&parseTime=True&loc=Local")if err != nil {panic(err)}DB, err = gorm.Open(mysql.New(mysql.Config{Conn: db,}))//都可以增删改查//db.Query("")//DB.Find("")
}
PostgreSQL
简单连接
package mainimport ("gorm.io/driver/postgres" //驱动库"gorm.io/gorm"
)func main() {dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"db, err := gorm.Open(postgres.Open(dsn))if err != nil {panic(err)}db.Exec("")
}
postgres.New
package mainimport ("gorm.io/driver/postgres""gorm.io/gorm"
)func main() {dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"db, err := gorm.Open(postgres.New(postgres.Config{DSN: dsn,PreferSimpleProtocol: true,}))if err != nil {panic(err)}db.Exec("")
}
通过sql.DB初始化*gorm.DB
package mainimport ("database/sql""gorm.io/driver/postgres""gorm.io/gorm"
)var DB *gorm.DBfunc main() {dsn := "host=localhost user=gorm password=gorm dbname=gorm port=9920 sslmode=disable TimeZone=Asia/Shanghai"sqlDB, _ := sql.Open("pgx", dsn)db, err := gorm.Open(postgres.New(postgres.Config{Conn: sqlDB,PreferSimpleProtocol: true,}))if err != nil {panic(err)}DB = db
}
SQL Server
简单连接
package mainimport ("gorm.io/driver/sqlserver""gorm.io/gorm"
)func main() {dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"db, err := gorm.Open(sqlserver.Open(dsn))if err != nil {panic(err)}
}
sqlserver.New
package mainimport ("gorm.io/driver/sqlserver""gorm.io/gorm"
)func main() {dsn := "sqlserver://gorm:LoremIpsum86@localhost:9930?database=gorm"db, err := gorm.Open(sqlserver.New(sqlserver.Config{DSN: dsn,}))
}
通过sql.DB初始化*gorm.DB
package mainimport ("database/sql""gorm.io/driver/sqlserver""gorm.io/gorm"
)func main() {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数据
package mainimport ("gorm.io/driver/sqlite" //驱动库"gorm.io/gorm"
)func main() {db, err := gorm.Open(sqlite.Open("gorm.db")) //参数名随便,后缀也可以随便只要合法就可以/*SQLite 数据库文件并不一定要以 .db 为后缀名。SQLite 是一个非常灵活的数据库系统,它不关心文件的扩展名是什么。可以使用任何合法的文件名,包括但不限于 .db、.sqlite、.db3(这是 SQLite 默认的文件扩展名之一)或者其他任何您喜欢的名称*/
}
另外,连接SQLite数据库时,也可以在内存中创建临时数据库,而需要一个实际的数据库,SQLite 允许您使用特殊的语法来创建一个基于内存的数据库,这个数据库不会持久化到磁盘上,而是存储在内存中,基于内存的数据库在程序结束时会自动销毁,所有数据都会丢失。如果您需要在程序之间保留数据,您应该使用存储在磁盘上的数据库文件。
使用 :memory:
伪路径创建基于内存的数据库:
db, err := gorm.Open(sqlite.Open(":memory:"), &gorm.Config{})
使用 :memory:
会创建一个新的基于内存的数据库,每次程序运行时都会重新创建。这个数据库在程序结束时自动销毁。
使用 file::memory:
伪路径创建基于内存的数据库:
db, err := gorm.Open(sqlite.Open("file::memory:"), &gorm.Config{})
file::memory:
与 :memory:
相似,也是创建基于内存的数据库。但是,file::memory:
允许 SQLite 使用更多的文件接口功能。
使用 file::memory:?cache=shared
创建共享缓存的基于内存数据库:
db, err := gorm.Open(sqlite.Open("file::memory:?cache=shared"), &gorm.Config{})
使用 cache=shared
参数可以创建一个所有数据库连接都共享同一数据库状态缓存的基于内存数据库。这可以提高并发访问数据库的性能。
gorm.Config
gorm.Config实现了Option接口,因此我们可以将gorm.Config传递给gorm.Open函数,gorm.Config的源码
// Config GORM config
type Config struct {//跳过默认事务SkipDefaultTransaction bool// 命名策略,可以定义表名,列表等生成规则NamingStrategy schema.Namer// 在创建或更新时,是否更新关联数据FullSaveAssociations bool// 日志接口,用于实现自定义日志Logger logger.Interface// 创建时间使用的函数NowFunc func() time.Time// 生成 SQL 但不执行,可以用于准备或测试生成的 SQLDryRun bool// 是否禁止创建 prepared statement 并将其缓存PrepareStmt bool// 禁止去ping数据库,检测是否可用DisableAutomaticPing bool// 是否禁止自动创建外键约束DisableForeignKeyConstraintWhenMigrating bool// 是否禁止嵌套事务DisableNestedTransaction bool// 是否允许全局update/deleteAllowGlobalUpdate bool// 执行查询时,是否带上所有字段QueryFields bool// 默认批量插入大小CreateBatchSize int
}
连接池
通过数据库连接池,我们可以避免频繁创建和销数据库连接所带来的开销,GROM的数据连接池底层是通过database/sql来实现的,所以其设置方法与database/sql
是一样的
sqlDB, err := db.DB()// SetMaxIdleConns 设置空闲连接池中连接的最大数量
sqlDB.SetMaxIdleConns(10)// SetMaxOpenConns 设置打开数据库连接的最大数量。
sqlDB.SetMaxOpenConns(100)// SetConnMaxLifetime 设置了连接可复用的最大时间。
sqlDB.SetConnMaxLifetime(time.Hour)
关闭数据库
程序执行结束后,需要关闭数据连接,而GORM的底层仍然是通过database/sql去连接数据库的,因此要通过gorm.DB对象的DB()方法返回的sql.DB
来关闭数据库连接
sqlDB, err := db.DB()sqlDB.Close()//defer sqlDB.Close()