数据库连接
首先安装gorm并且安装mysql驱动
go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql
连接数据库
dsn := "root:root@tcp(127.0.0.1:13306)/test?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{NamingStrategy: schema.NamingStrategy{SingularTable: true}})
if err != nil {
panic("failed to connect database")
}
Modle & Table
//对应Mysql中 user_info表
type UserInfo struct {
Id int
Email string
Name string
Age int
}
var usr []user.UserInfo
//指定MYSQL中表名查询
db.Table("user_info").Where("name = ?", "lili").Scan(&dU)
//使用结构体查询
db.Model(&usr).Where("name = ?", "lili").Scan(&dU)
Scan
在查询多个数据时把数据返回给一个新的结构体可以使用Scan方法
//UserInfo结构体对应MYSQL中user_info表
type UserInfo struct{
Id int
Email string
title string
Age int
}
//定义UserDomain结构体用来接收SQL查询后返回的数据
type UserDomain struct{
name string
Age int
}
var usr []UserInfo
var dU []UserDomain
//将查询的数据返回给UserDomain
db.Where("age > 10 or email like ?", "%@163.com").Find(&usr).Scan(&dU)
fmt.Printf("%+v\n", usr)
fmt.Printf("%+v\n", dU)
//打印usr返回结果
[{Id:1 Email:test@163.com Name:lili Age:80} {Id:2 Email:asd@163.com Name:lili Age:13} {Id:6 Email:test2@163.com Name:李虎 Age:28}]
//打印dU返回结果
[{Name:lili Age:80} {Name:lili Age:13} {Name:李虎 Age:28}]
使用Scan方法时,结构体的下成员名称和数据库中的值不一样时,可以通过column更改.
例如 mysql中 name字段 在结构体中叫title
// 只需要增加column字段对应mysql中的字段名
type UserDomain struct{
name string `gorm:"column:name"`
Age int
}
排序
使用Order方法
desc 降序(从高到底) asc 升序(从低到高)
Preload
使用Preload方法可以实现查询所关联其他表的信息一起返回
var usr User
db.Preload("Articles").Take(&usr)
fmt.Printf("%+v\n", usr)
分页查询
var usr []user.UserInfo
//一页多少条
limi := 2
//第几页
page :=1
//页数是从0开始需要 -1 * 条数
offset := (page-1) * limit
db.Limit(limit).Offset(offset).Find(&usr)
子查询
查询大于平均年龄的用户(先算出所有用户的平均年龄, 在找出大于这个平均年龄的数据)
# 原生sql
# select * from students where age > (select avg(age) from students);
var users []Student
DB.Model(Student{}).Where("age > (?)", DB.Model(Student{}).Select("avg(age)")).Find(&users)
fmt.Println(users)
单表查询
定义UserInfo结构体,对应数据库中user_info表
type UserInfo struct {
Id int
Email string
Name string
Age int
}
精准查询
var usr []user.UserInfo
//精准匹配
//在usr_info表里找name为 lili 的数据
err = db.Where("name=?", "lili").Find(&usr).Error //方法1
err = db.Find(&usr, "name=?", "lili").Error //方法2
//在usr_info表里找name!=lili的数据
//返回的是数据
err = db.Not("name=?", "lili").Find(&usr).Error //方法1
err = db.Where("not name=?", "lili").Find(&usr).Error //方法2
//返回的是条数
data := db.Not("name=?", "lili").Find(&usr).RowsAffected
//在usr_info表里找name为 lili, 小红
db.Find(&usr, "name in ?", []string{"lili", "小红"})
模糊查询
//模糊匹配
//在usr_info表里找name中有li的数据
db.Where("name like ?", "李%").Find(&usr) //找李开头的所有数据
db.Where("name like ?", "李_").Find(&usr) //找李开头的2个字数据
db.Where("name like ?", "李__").Find(&usr) //找李开头的3个字数据
// 在usr_info表里找age > 10 和 email是163邮箱的数据
db.Where("age > 10 and email like ?", "%@163.com").Find(&usr) //方法1
db.Where("age > 10").Where("email like ?", "%@163.com").Find(&usr) //方法2
// 在usr_info表里找age > 10 或者 email是163邮箱的数据
db.Where("age > 10 or email like ?", "%@163.com").Find(&usr) //方法1
db.Where("age > 10").Or("email like ?", "%@163.com").Find(&usr) //方法2
一对多关系
在gorm中,官方文档是把一对多关系分为了两类
Belongs To 属于谁 , Has Many 我拥有的
//重写关联外键
type User struct {
UID uint
Name string
Articles []Article `gorm:"foreignKey:UID"` // 用户拥有的文章列表,文章表外键
}
type Article struct {
ID uint
Title string
UID uint
User User `gorm:"foreignKey:UID"` // 属于User
}
创建用户,并且创建文章
t1 := Article{Title: "你好go语言"}
t2 := Article{Title: "go是未来"}
usr := User{Name: "lili", Articles: []Article{t1, t2}}
db.Debug().Create(&usr)
创建文章,关联已有用户
db.Create(&Article{
Title: "够浪够浪够浪",
UID: 212,
})
//传对象
var usr User
db.Find(&usr).Where("uid =?", 105)
db.Create(&Article{Title: "0基础入门", UID: usr.UID})