Gorm使用
简介
什么是orm
代码结构和数据库架构一致,代码行为就是数据库行为。
为什么选择gorm?
作者中国人
文档全面
维护稳定,用户庞大
功能全面,符合开发习惯
重点
数据库连接、建表和自动迁移
模型建立
单表的增删改查
一对多、一对一、多对多关系的增删改查
特殊的增删改查
事务的操作
自定义的数据类型
钩子(生命周期HOOK函数)
DBResolver读写分离(多数据库)
连接MySQL以及建表和自动迁移
安装gorm
安装gorm工具:"gorm.io/gorm"
安装mysql驱动:"gorm.io/driver/mysql"
安装sqlite驱动:"gorm.io/driver/sqlite"
连接mysql
func main() {
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
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{})
print(db, err)
}
一般使用过程中需要配置更多参数:
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "gorm:gorm@tcp(127.0.0.1:3306)/gorm?charset=utf8&parseTime=True&loc=Local", // 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, // 根据版本自动配置
}), &gorm.Config{}
查看源码可以看到可以配置的选项。
这些配置是非常重要的。
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "root:root@tcp(127.0.0.1:3306)/gorm_class?charset=utf8mb4&parseTime=True&loc=Local",
DefaultStringSize: 171,
}), &gorm.Config{
SkipDefaultTransaction: false,
NamingStrategy: schema.NamingStrategy{
TablePrefix: "t_", //表名前缀,`user`的表名是t_users
SingularTable: true, //使用单数表名,启用后`User`的表名应该是`t_user`
},
DisableForeignKeyConstraintWhenMigrating: true, //逻辑外键
})
创建表
定义一个结构体,对应数据库中表的结构。
model.go
package main
import (
"database/sql"
"time"
)
type TestUser struct {
ID uint
Name string
Email *string
Age uint8
Birthday *time.Time
MemberNumber sql.NullString
ActivedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
type Model struct {
UUID uint `gorm:"primaryKey"`
Time time.Time `gorm:"column:my_time"`
}
type TestMyUser struct {
Model Model `gorm:"embedded"`
Name string `gorm:"default:qm"`
Email *string `gorm:"not null"`
Age uint8 `gorm:"comment:年龄"`
Birthday *time.Time
MemberNumber sql.NullString
ActivedAt sql.NullTime
CreatedAt time.Time
UpdatedAt time.Time
}
func TestUserCreate() {
GLOBAL_DB.AutoMigrate(&TestMyUser{})
}
main.go
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
// go get -u gorm.io/gorm
// go get -u gorm.io/driver/mysql
var GLOBAL_DB *gorm.DB
func main() {
// 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: "root:root@tcp(127.0.0.1:3306)/gorm_class?charset=utf8mb4&parseTime=True&loc=Local",
DefaultStringSize: 171,
}), &gorm.Config{
// SkipDefaultTransaction: false,
// NamingStrategy: schema.NamingStrategy{
// TablePrefix: "ga_", //表名前缀,`user`的表名是t_users
// //SingularTable: true, //使用单数表名,启用后`User`的表名应该是`t_user`
// },
// DisableForeignKeyConstraintWhenMigrating: true, //逻辑外键
})
//自动建表
//db.AutoMigrate(&User{})
//手动建表
// M := db.Migrator()
// //M.CreateTable(&User{}) //创建表
// fmt.Println(M.HasTable(&User{})) //表是否存在
// //fmt.Println(M.HasTable("ga_users")) //表是否存在
// if M.HasTable(&User{}) {
// M.DropTable(&User{})
// } else {
// M.CreateTable(&User{})
// }
// //获取通用数据库对象sql.DB
// sqlDB, err := db.DB()
// //Ping
// //sqlDB.Ping()
// sqlDB.SetMaxIdleConns(10) //连接池钟最大的空闲数
// sqlDB.SetMaxOpenConns(100) //设置数据库的最大连接数
GLOBAL_DB = db
TestUserCreate() //创建model中的TestUser
fmt.Println(db, err)
}
AutoMigrate方法会自动创建数据表。