中文文档v1:jinzhu版: https://v1.gorm.io/zh_CN/docs/
中文文档v2:gorm.io版: https://gorm.io/zh_CN/
当前博客内容参考v1版本做的,v2版本与当前笔记可能会有所差别
安装GORM
go get -u github.com/jinzhu/gorm
连接数据库
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql" //引入mysql的驱动
)
func main() {
//连接数据库:
//Open传入两个参数:
//第一个参数:指定你要连接的数据库
//第二个参数:指的是数据库的设置信息:用户名:密码@tcp(ip:port)/数据库名字?charset=utf8&parseTime=True&loc=Local
//charset=utf8设置字符集
//parseTime=True为了处理time.Time
//loc=Local 时区设置,与本地时区保持一致
db, err := gorm.Open("mysql", "root:admin@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err) //如果出错,后续代码没有必要执行,想让程序中断,panic来执行即可
}
//数据库资源释放:
defer db.Close()
}
运行
如果运行中报错如下
missing go.sum entry for module providing package github.com/go-sql-driver/mysql (imported by github.com/jinzhu/gorm/dialects/mysql); to add:
执行如下命令即可解决
go get -u github.com/go-sql-driver/mysql
创建和删除表以及判断表是否存在
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// 定义结构体:
type User struct {
Age int
Name string
}
func main() {
//连接数据库:
db, err := gorm.Open("mysql", "root:admin@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err) //如果出错,后续代码没有必要执行,想让程序中断,panic来执行即可
}
//数据库资源释放:
defer db.Close()
//创建表:通常情况下,数据库中新建的标的名字是结构体名字的复数形式,例如结构体User,表名 users
db.CreateTable(&User{
})
//Table方法可以指定你要创建的数据库的表名
db.Table("user").CreateTable(&User{
})
//删除表:
//db.DropTable(&User{}) //通过&User{}来删除users表
//db.DropTable("user") //通过"user"删除user表
//判断表是否存在:
flag1 := db.HasTable(&User{
}) //判断是否有users表
fmt.Println(flag1)
flag2 := db.HasTable("user") //判断是否有user表
fmt.Println(flag2)
}
简单的增删改查
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
//定义结构体:
type User struct {
Age int
Name string
}
func main(){
//连接数据库:
db,err := gorm.Open("mysql","root:admin@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err) //如果出错,后续代码没有必要执行,想让程序中断,panic来执行即可
}
//数据库资源释放:
defer db.Close()
//创建表:通常情况下,数据库中新建的标的名字是结构体名字的复数形式,例如结构体User,表名 users
db.CreateTable(&User{
})
//增删改查:
//增加数据:
// db.Create(&User{Age:18,Name:"丽丽"})
//查询数据:第一个参数:查询出来的数据的载体:
var myuser User
db.First(&myuser,"age = ?",18)
fmt.Println(myuser)
//更新数据:
//需要做的:先查询,再更新
db.Model(&myuser).Update("age",30)
db.Model(&myuser).Update("name","菲菲")
//删除数据:
//需要做的:先查询,再删除
db.Delete(&myuser)
}
模型名与表名的映射
【1】模型名和表名的映射规则:
(1)如果模型名没有驼峰命名,那么表名就是:模型名小写+复数形式: 如模型名User-》表名users
(2)如果模型名有驼峰命名,那么表名就是:大写变小写并在前面加下划线,最后加复数形式:如模型名UserInfo-》表名user_infos
(3)如有模型名有连续的大写字母,那么表名就是:连续的大写字母变小写,驼峰前加下划线,字母变小写,最后加复数形式:如模型名:DBUserInfo-》表名db_user_infos
PS:模型中字段名称与表中列名的映射规则同上,学习视频中未曾演示,可自行练习使用
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
// 定义结构体:
type User struct {
Age int
Name string
}
type UserInfo struct {
Age int
Name string
}
type DBUserInfo struct {
Age int
Name string
}
type MyUser struct {
Age int
Name string
}
func (MyUser) TableName() string {
return "test_my_user"
}
func main() {
//连接数据库:
db, err := gorm.Open("mysql", "root:admin@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err) //如果出错,后续代码没有必要执行,想让程序中断,panic来执行即可
}
//数据库资源释放:
defer db.Close()
//创建表:通常情况下,数据库中新建的标的名字是结构体名字的复数形式,例如结构体User,表名 users
db.CreateTable(&User{
})
db.CreateTable(&UserInfo{
})
db.CreateTable(&DBUserInfo{
})
db.CreateTable(&MyUser{
})
}
gorm.Model_匿名字段
【1】gorm.Model匿名字段
只需要在自己的模型中指定gorm.Model匿名字段,即可在数据库表中包含四个字段:ID,CreatedAt,UpdatedAt,DeletedAt
ID:主键自增长
CreatedAt:用于存储记录的创建时间
UpdatedAt:用于存储记录的修改时间
DeletedAt:用于存储记录的删除时间
【2】代码:
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type MyUser2 struct {
//增加一个匿名字段:
gorm.Model
Age int
Name string
}
func main() {
//连接数据库:
db, err := gorm.Open("mysql", "root:admin@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err) //如果出错,后续代码没有必要执行,想让程序中断,panic来执行即可
}
//数据库资源释放:
defer db.Close()
//创建表:
db.CreateTable(&MyUser2{
})
}
结构体标签gorm
【1】通过结构体标签gorm来实现表的约束
【2】gorm标签属性值:
(1)-: 忽略,不映射这个字段 eg: gorm:"-"
,适合:一些冗余字段,不想在数据库中体现,只想在结构体中体现
(2)primary_key:主键 eg: gorm:"primary_key"
PS:如果是想要加联合主键,在每个字段后加入 gorm:"primary_key"
即可
例如:即可将StuID和Name作为联合主键
(3)AUTO_INCREMENT:自增 eg: gorm:"AUTO_INCREMENT"
(4)not null:不为空,默认为空 eg: gorm:"not null"
(5)index:索引, eg: gorm:"index"
创建索引并命名:eg: gorm:"index:idx_name_code"
(6)unique_index:唯一索引 eg: gorm:"unique_index"
唯一性索引unique index和一般索引normal index最大的差异就是在索引列上增加了一层唯一约束。添加唯一性索引的数据列可以为 空,但是只要存在数据值,就必须是唯一的。
(7)unique:唯一 eg: gorm:"unique"
(8)column:指定列名 eg: gorm:"column:user_name"
(9)size:字符串长度,默认为255 eg:gorm:"size:10"
(10)default default:'男'
默认值
(11)type:设置sql类型 eg: gorm:"type:int(2)"
PS:多个属性值之间用分号分隔
结构体代码
type Student struct {
StuID int `gorm:"primary_key;AUTO_INCREMENT"`
Name string `gorm:"not null"`
Age int `gorm:"unique_index"`
Email string `gorm:"unique"`
Sex string `gorm:"column:gender;size:10"`
Desc string `gorm:"-"`
Classno string `gorm:"type:int"`
}
多表操作
表关系
根目录下创建demostruct/demostruct.go
文件
一对一
demostruct.go
package demostruct
type User struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
//关联关系
User User
//指定外键
UserId int
}
main.go
package main
import (
"demo01/demostruct"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type MyUser2 struct {
//增加一个匿名字段:
gorm.Model
Age int
Name string
}
func main() {
//连接数据库:
db, err := gorm.Open("mysql", "root:admin@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err) //如果出错,后续代码没有必要执行,想让程序中断,panic来执行即可
}
//数据库资源释放:
defer db.Close()
//创建表:
//创建表:通常情况下,数据库中新建的标的名字是结构体名字的复数形式,例如结构体User,表名 users
db.CreateTable(&demostruct.User{
})
db.CreateTable(&demostruct.UserInfo{
})
}
PS:并没有在数据库中强制加入外键,只是一种关联关系而已
【1】通过gorm标签来指定外键:(属于关系:关系和外键的指定在同一方)
package demostruct
type User struct{
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
//关联关系
User User `gorm:"ForeignKey:MyUserID;AssociationForeignKey:UserId"`
//指定外键:
MyUserID int
}
【2】通过gorm标签来指定外键:(包含关系:关系和外键的指定不在同一方)
package demostruct
type User struct{
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
//指定外键:
IID int
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
//关联关系
User User `gorm:"ForeignKey:IID;AssociationForeignKey:InfoID"`
}
一对多
demostruct.go
package demostruct
type Author struc