Gorm和Mysql驱动的安装
打开终端,输入下列命令即可:
go get gorm.io/driver/mysql go get gorm.io/gorm
Gorm连接数据库
示例
package main import ( "fmt" "github.com/sirupsen/logrus" "gorm.io/driver/mysql" "gorm.io/gorm" ) func init() { //数据库连接信息 username := "root" password := "123456" databasename := "gorm" localHost := "localhost" port := 3306 dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, localHost, port, databasename) db, err := gorm.Open(mysql.Open(dns)) if err != nil { logrus.Error("数据库连接失败", err) } fmt.Println("数据库连接成功", db) } func main() { }
数据库连接的细节
- 跳过默认事务
为了保证数据一致性,Gorm会在事务中去执行去执行增删查改,如果我们没有这个需求可以选择跳过默认事务:
db, err := gorm.Open(mysql.Open(dns),&gorm.Config{SkipDefaultTransaction: true})
- 命名策略
在grom中默认表名是复数,字段是单数,比如下面我们创建一张student
表,代码是这样的:
package main import ( "fmt" "github.com/sirupsen/logrus" "gorm.io/driver/mysql" "gorm.io/gorm" ) var dB *gorm.DB type Student struct { Name string Age int Sex string } func init() { //数据库连接信息 username := "root" password := "ba161754" databasename := "gorm" localHost := "localhost" port := 3306 dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, localHost, port, databasename) db, err := gorm.Open(mysql.Open(dns), &gorm.Config{SkipDefaultTransaction: true}) if err != nil { logrus.Error("数据库连接失败", err) } dB = db } func main() { err := dB.AutoMigrate(Student{}) if err != nil { logrus.Error("数据库迁移失败", err) } fmt.Println("创建表成功") }
创建出来的表是这样的:
当然我们也可以尝试修改这种命名策略:
db, err := gorm.Open(mysql.Open(dns), &gorm.Config{SkipDefaultTransaction: true, NamingStrategy: schema.NamingStrategy{ // TablePrefix: "t_", //表名前缀 SingularTable: false, //禁用表名复数 NoLowerCase: false, //禁用小写 }})
- 日志显示
func initLogger() { var mysqlLogger logger.Interface mysqlLogger = logger.Default.LogMode(logger.Info) //设置日志打印级别 mysqlLogger = logger.New( log.New(os.Stdout, "\r\n", log.LstdFlags), // (日志输出的目标,前缀和日志包含的内容) logger.Config{ SlowThreshold: time.Second, // 慢 SQL 阈值 LogLevel: logger.Info, // 日志级别 IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误 Colorful: true, // 使用彩色打印 }, ) dB.Logger = mysqlLogger }
完整代码,仅供参考:
package main import ( "fmt" "github.com/sirupsen/logrus" "gorm.io/driver/mysql" "gorm.io/gorm" "gorm.io/gorm/logger" "gorm.io/gorm/schema" "log" "os" "time" ) var dB *gorm.DB type Student struct { Name string Age int Sex string } func ConnectDB() { //数据库连接信息 username := "root" password := "ba161754" databasename := "gorm" localHost := "localhost" port := 3306 var err error dns := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, localHost, port, databasename) dB, err = gorm.Open(mysql.Open(dns), &gorm.Config{SkipDefaultTransaction: true, NamingStrategy: schema.NamingStrategy{ // TablePrefix: "t_", //表名前缀 SingularTable: false, //禁用表名复数 NoLowerCase: false, //禁用小写 }}) if err != nil { logrus.Error("数据库连接失败", err) } } func initLogger() { var mysqlLogger logger.Interface mysqlLogger = logger.Default.LogMode(logger.Info) //设置日志打印级别 mysqlLogger = logger.New( log.New(os.Stdout, "\r\n", log.LstdFlags), // (日志输出的目标,前缀和日志包含的内容) logger.Config{ SlowThreshold: time.Second, // 慢 SQL 阈值 LogLevel: logger.Info, // 日志级别 IgnoreRecordNotFoundError: true, // 忽略ErrRecordNotFound(记录未找到)错误 Colorful: true, // 使用彩色打印 }, ) dB.Logger = mysqlLogger } func init() { ConnectDB() initLogger() } func main() { err := dB.AutoMigrate(Student{}) if err != nil { logrus.Error("数据库迁移失败", err) } fmt.Println("创建表成功") }
模型定义
模型定义示例
模型是使用普通结构体定义的。 这些结构体可以包含具有基本Go类型、指针或这些类型的别名,甚至是自定义类型(只需要实现 database/sql 包中的Scanner和Valuer接口)我们来看一下Gorm给出的user
模型示例:
type User struct { ID uint // Standard field for the primary key Name string // 一个常规字符串字段 Email *string // 一个指向字符串的指针, allowing for null values Age uint8 // 一个未签名的8位整数 Birthday *time.Time // A pointer to time.Time, can be null MemberNumber sql.NullString // Uses sql.NullString to handle nullable strings ActivatedAt sql.NullTime // Uses sql.NullTime for nullable time fields CreatedAt time.Time // 创建时间(由GORM自动管理) UpdatedAt time.Time // 最后一次更新时间(由GORM自动管理) }
这里常见的uint
这种类型就不做过多介绍了,这里主要是 有两个类型我们这里进行一下介绍:
*string(指针类型)
:如果我们在这里使用string
类型的话,这里我们是可以写空值的,如果我们用string
类型是不允许出现空值的sql.NullString
:sql.NullString
是 Go 语言标准库中的一个数据类型,位于 database/sql 包中。它用于表示数据库中可能为 NULL 的字符串值。它由两个字段组成:String
用于保存字符串值(如果不为 NULL),Valid
是一个布尔标志,指示字符串值是否为 NULL。在与允许字符串列包含 NULL 值的数据库一起工作时,这种类型特别有用。
type NullString struct { String string Valid bool // Valid is true if String is not NULL }
gorm.Model
在开始介绍gorm.Model
之前,我们先讲一下几条在gorm
的约定:
-主键:GORM 使用一个名为ID 的字段作为每个模型的默认主键。
- 表名:默认情况下,GORM 将结构体名称转换为 snake_case 并为表名加上复数形式。 例如,一个 User 结构体在数据库中的表名变为 users 。
- 列名:GORM 自动将结构体字段名称转换为 snake_case 作为数据库中的列名。
- 时间戳字段:GORM使用字段 CreatedAt 和 UpdatedAt 来自动跟踪记录的创建和更新时间。
而在grom
中存在gorm.Model
这一预定义的结构体,我们可以将它直接嵌入我们所定义的结构体中,这保证了不同模型之间保持一致性并利用GORM
内置的约定,gorm.model
的定义如下:
type Model struct { ID uint `gorm:"primarykey"` CreatedAt time.Time UpdatedAt time.Time DeletedAt DeletedAt `gorm:"index"` }
它主要包含以下字段:
- ID :每个记录的唯一标识符(主键)。
- CreatedAt :在创建记录时自动设置为当前时间。
- UpdatedAt:每当记录更新时,自动更新为当前时间。
- DeletedAt:用于软删除(将记录标记为已删除,而实际上并未从数据库中删除)。
字段标签
在gorm
中我们一般使用字段标签来表示字段的类型,常见的字段类型主要有以下几种:
type
:定义字段类型size
:字段大小column
自定义别名primaryKey
将列定义为主键unique
将列定义为唯一键default
定义列的默认值not null
不可为空embedded
嵌套字段embeddedPrefix
嵌套字段前缀comment
注释
示例:
type StudentInfo struct { Email *string `gorm:"size:32"` // 使用指针是为了存空值 Addr string `gorm:"column:y_addr;size:16"` Gender bool `gorm:"default:true"` } type Student struct { Name string `gorm:"type:varchar(12);not null;comment:用户名"` UUID string `gorm:"primaryKey;unique;comment:主键"` Info StudentInfo `gorm:"embedded;embeddedPrefix:s_"` }