var users []Student
//查询用户名是枫枫的,存储在users中
DB.Where("name = ?", "枫枫").Find(&users)
fmt.Println(users)
//查询名字不是枫枫的
DB.Where("name <> ?", "枫枫").Find(&users)
fmt.Println(users)
// 查询用户名包含 如燕,李元芳的
DB.Where("name in ?", []string{"如燕", "李元芳"}).Find(&users)
fmt.Println(users)
// 查询姓李的
DB.Where("name like ?", "李%").Find(&users)
fmt.Println(users)
// 查询年龄大于23,是qq邮箱的
DB.Where("age > ? and email like ?", "23", "%@qq.com").Find(&users)
fmt.Println(users)
// 查询是qq邮箱的,或者是女的
DB.Where("gender = ? or email like ?", false, "%@qq.com").Find(&users)
fmt.Println(users)
使用结构体查询
使用结构体会过滤零值,如果是查询条件是零值的话,会不考虑这个条件
并且结构体中的条件都是and关系
//结构体查询会过滤零值
DB.Where(&Student{Name: "元芳", Age: 12}).Find(&users)
fmt.Println(users)
使用map查询
不会过滤零值
//map不会过滤零值
DB.Where(map[string]any{"name": "元芳", "age": 0}).Find(&users)
fmt.Println(users)
Not
// 排除年龄大于23的
DB.Not("age > 23").Find(&users)
fmt.Println(users)
Or
DB.Or("gender = ?", false).Or(" email like ?", "%@qq.com").Find(&users)
fmt.Println(users)
Select
没有被选中,会被赋零值
DB.Select("name", "age").Find(&users)
fmt.Println(users)
//也可以存入另一个结构体中
type User struct {
Name string
Age int
}
var students []Student
var users []User
DB.Select("name", "age").Find(&students).Scan(&users)
fmt.Println(users)
//这样会查询两次
查询一次的话有两种方法
var users []User
DB.Model(&Student{}).Select("name", "age").Scan(&users)
fmt.Println(users)
var users []User
DB.Table("student").Select("name", "age").Scan(&users)
fmt.Println(users)
排序
var users []Student
DB.Order("age desc").Find(&users)
fmt.Println(users)
// desc 降序
// asc 升序
分页查询
var users []Student
// 一页两条,第1页
DB.Limit(2).Offset(0).Find(&users)
fmt.Println(users)
// 第2页
DB.Limit(2).Offset(2).Find(&users)
fmt.Println(users)
// 第3页
DB.Limit(2).Offset(4).Find(&users)
fmt.Println(users)
更通用的方法
var users []Student
//一页多少条
limit := 2
//第几页
page := 1
offset := (page - 1) * limit
DB.Limit(limit).Offset(offset).Find(&users)
fmt.Println(users)
加个for循环打印出所有的
var users []Student
limit := 2 // 每页多少条
page := 1 // 从第一页开始
offset := 0 // 偏移量
for {
// 计算偏移量
offset = (page - 1) * limit
// 查询当前页的数据
DB.Limit(limit).Offset(offset).Find(&users)
// 如果当前页没有数据了,说明已经查询完所有数据
if len(users) == 0 {
break
}
// 打印当前页的数据
fmt.Println(users)
// 清空切片,准备下一次查询
users = []Student{}
// 增加页码
page++
}
去重
//去重
var ageList []int
DB.Table("students").Select("age").Distinct("age").Scan(&ageList)
//或者
//DB.Table("students").Select("distinct age").Scan(&ageList)
fmt.Println(ageList)
分组查询
//查询男生的人数和女生的个数
var ageList []int
DB.Table("students").Select("count(id)").Group("gender").Scan(&ageList)
fmt.Println(ageList)
//精确一点
type AggeGroup struct {
Gender int
Count int `gorm:"column:count(id)"`
}
var agge []AggeGroup
//查询男生的个数和女生的个数
DB.Table("students").Select("count(id)", "gender").Group("gender").Scan(&agge)
fmt.Println(agge)
//更精确一点
type AggeGroup struct {
Gender int
Count int `gorm:"column:count(id)"`
Name string `gorm:"column:group_concat(name)"`
}
//GROUP_CONCAT是 MySQL 中的一个聚合函数,用于将分组内的某个字段值连接成一个字符串
var agge []AggeGroup
//查询男生的个数和女生的个数
DB.Table("students").Select("count(id)", "gender", "group_concat(name)").Group("gender").Scan(&agge)
fmt.Println(agge)
执行原生sql
type AggeGroup struct {
Gender int
Count int `gorm:"column:count(id)"`
Name string `gorm:"column:group_concat(name)"`
}
var agge []AggeGroup
DB.Raw(`SELECT count(id), gender, group_concat(name) FROM students GROUP BY gender`).Scan(&agge)
fmt.Println(agge)
子查询
# 原生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)
命名参数
var users []Student
DB.Where("name = @name and age = @age", sql.Named("name", "枫枫"), sql.Named("age", 23)).Find(&users)
DB.Where("name = @name and age = @age", map[string]any{"name": "枫枫", "age": 23}).Find(&users)
fmt.Println(users)
Find到map
var res []map[string]any
DB.Table("students").Find(&res)
fmt.Println(res)
查询引用scope
可以再model层写一些通用的查询方式,这样外界就可以直接调用方法即可
func Age23(db *gorm.DB) *gorm.DB {
return db.Where("age > ?", 23)
}
func main(){
var users []Student
DB.Scopes(Age23).Find(&users)
fmt.Println(users)
}