Gorm和Mysql驱动的安装
打开终端,输入下列命令即可:
go get gorm.io/driver/mysql
go get gorm.io/gorm
Gorm连接数据库
示例
package mainimport ("fmt""github.com/sirupsen/logrus""gorm.io/driver/mysql""gorm.io/gorm"
)func init() {//数据库连接信息username := "root"password := "123456"databasename := "gorm"localHost := "localhost"port := 3306dns := 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 mainimport ("fmt""github.com/sirupsen/logrus""gorm.io/driver/mysql""gorm.io/gorm"
)var dB *gorm.DBtype Student struct {Name stringAge intSex string
}func init() {//数据库连接信息username := "root"password := "ba161754"databasename := "gorm"localHost := "localhost"port := 3306dns := 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.InterfacemysqlLogger = 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 mainimport ("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.DBtype Student struct {Name stringAge intSex string
}func ConnectDB() {//数据库连接信息username := "root"password := "ba161754"databasename := "gorm"localHost := "localhost"port := 3306var err errordns := 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.InterfacemysqlLogger = 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 keyName string // 一个常规字符串字段Email *string // 一个指向字符串的指针, allowing for null valuesAge uint8 // 一个未签名的8位整数Birthday *time.Time // A pointer to time.Time, can be nullMemberNumber sql.NullString // Uses sql.NullString to handle nullable stringsActivatedAt sql.NullTime // Uses sql.NullTime for nullable time fieldsCreatedAt 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 stringValid 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.TimeUpdatedAt time.TimeDeletedAt 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_"`
}