1. 用Struct或Map接收数据
1.1 Find到Struct
定义一个小的结构体来接收表中的查询结果
| db.Model(User{}).Find(&UserModels) |
| mysql> select * from users; |
| + |
| | id | name | age | email | |
| + |
| | 1 | LiuBei | 28 | liubei@xishu.com | |
| | 2 | GuanYu | 22 | guanyu@xishu.com | |
| | 3 | ZhangFei | 20 | zhangfei@xishu.com | |
| + |
| 3 rows in set (0.00 sec) |
代码
| package main |
| |
| import ( |
| "database/sql" |
| "fmt" |
| "gorm.io/driver/mysql" |
| "gorm.io/gorm" |
| "time" |
| ) |
| |
| type User struct { |
| ID int64 |
| Age int64 |
| Name string |
| Email string |
| } |
| |
| type userModel struct { |
| ID int64 |
| Name string |
| } |
| |
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var UserModels []userModel |
| db.Model(User{}).Find(&UserModels) |
| fmt.Println(UserModels) |
| } |
| |
| func connect() (db *gorm.DB,sqlDB *sql.DB,err error) { |
| dsn := "root:40010355@tcp(127.0.0.1:3306)/crow?charset=utf8&parseTime=True&loc=Local" |
| db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) |
| sqlDB,_ = db.DB() |
| if err != nil { |
| fmt.Printf(err.Error()) |
| defer sqlDB.Close() |
| }else { |
| fmt.Printf("OK\n") |
| sqlDB.SetMaxIdleConns(10) |
| sqlDB.SetMaxOpenConns(100) |
| sqlDB.SetConnMaxLifetime(time.Hour) |
| } |
| return |
| } |
结果输出
| OK |
| [{1 LiuBei} {2 GuanYu} {3 ZhangFei}] |
1.2 Find到Map
定义一个Map来接收数据
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var users map[string]interface{} |
| db.Table("users").Find(&users) |
| fmt.Println(users) |
| } |
2. 子查询
| db.Where("age > (?)", db.Table("users").Select("AVG(age)")).Find(&users) |
| |
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var users []User |
| db.Where("age > (?)", db.Table("users").Select("AVG(age)")).Find(&users) |
| fmt.Println(users) |
| } |
| OK |
| [{1 28 LiuBei liubei@xishu.com}] |
3. Group/Having
3.1 Group
求和、平均值等情况的分组
| db.Table("users").Select("AVG(age) as avg_age","company").Group("company").Find(&users) |
完整示例
求下表中各公司的平均年龄
| mysql> select * from users; |
| + |
| | id | name | age | email | company | |
| + |
| | 1 | LiuBei | 28 | liubei@xishu.com | shu | |
| | 2 | GuanYu | 22 | guanyu@xishu.com | shu | |
| | 3 | ZhangFei | 20 | zhangfei@xishu.com | shu | |
| | 4 | SunQuan | 22 | sunquan@dongwu.com | wu | |
| | 5 | ZhouYu | 15 | zhouyu@dongwu.com | wu | |
| + |
| 5 rows in set (0.00 sec) |
| package main |
| |
| import ( |
| "database/sql" |
| "fmt" |
| "gorm.io/driver/mysql" |
| "gorm.io/gorm" |
| "time" |
| ) |
| |
| type User struct { |
| ID int64 |
| Age int64 |
| Name string |
| Email string |
| Company string |
| } |
| |
| type groupBy struct { |
| AvgAge float64 |
| Company string |
| |
| } |
| |
| |
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var users []groupBy |
| |
| db.Table("users").Select("AVG(age) as avg_age","company").Group("company").Find(&users) |
| fmt.Println(users) |
| } |
| |
| func connect() (db *gorm.DB,sqlDB *sql.DB,err error) { |
| dsn := "root:40010355@tcp(127.0.0.1:3306)/crow?charset=utf8&parseTime=True&loc=Local" |
| db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{}) |
| sqlDB,_ = db.DB() |
| if err != nil { |
| fmt.Printf(err.Error()) |
| defer sqlDB.Close() |
| }else { |
| fmt.Printf("OK\n") |
| sqlDB.SetMaxIdleConns(10) |
| sqlDB.SetMaxOpenConns(100) |
| sqlDB.SetConnMaxLifetime(time.Hour) |
| } |
| return |
| } |
| OK |
| [{23.3333 shu} {18.5 wu}] |
3.2 Having
对Group的结果进行过滤。上例中得到的结果,用Having得到平均值大于20的结果。
| db.Table("users").Select("AVG(age) as avg_age","company").Group("company").Having("avg_age > ?",20).Find(&users) |
4. 变量
4.1 使用sql.Named定义
| db.Where("age > @age AND company = @company", sql.Named("company", "shu"),sql.Named("age", 20)).Find(&users) |
4.2 使用map定义变量
| db.Where("age > @age AND company = @company",map[string]interface{}{"company": "shu","age":20}).First(&users) |
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var users []User |
| |
| checkUser := map[string]interface{}{ |
| "company":"shu", |
| "age":20, |
| } |
| |
| db.Where("age > @age AND company = @company",checkUser).First(&users) |
| fmt.Println(users) |
| } |
5. 用Rows() 迭代
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| rows, _ := db.Model(&User{}).Where("company = ?", "shu").Rows() |
| defer rows.Close() |
| |
| for rows.Next() { |
| var user User |
| |
| db.ScanRows(rows, &user) |
| fmt.Println(user) |
| } |
| } |
6. 查钩子
写一个查询钩子,当查询结果字段Company
为空时,替换为"群"
| func (u *User) AfterFind(tx *gorm.DB) (err error) { |
| if u.Company == "" { |
| u.Company = "qun" |
| } |
| return |
| } |
7. Pluck(单列查询)
| db.Model(&User{}).Pluck("name", &names) |
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var names []string |
| db.Model(&User{}).Pluck("name", &names) |
| fmt.Println(names) |
| } |
| [LiuBei GuanYu ZhangFei YuJi ZhaoYun] |
8. Scopes(调用查询函数)
8.1 使用
- 作用
我们可以使用Scopes调用事先创建好的函数。
- 样例
| db.Scopes(函数1,函数2).Find(&users) |
8.2 示例
创建一个函数用来查询年龄大约20岁的用户数据
| func ageGT20db (db *gorm.DB) *gorm.DB { |
| return db.Where("age > ?",20) |
| } |
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var users []User |
| |
| db.Scopes(ageGT20db).Find(&users) |
| fmt.Println(users) |
| } |
9. Count
| func main() { |
| db,sqlDB,_ := connect() |
| defer sqlDB.Close() |
| |
| var count int64 |
| var users []User |
| |
| db.Find(&users).Count(&count) |
| fmt.Println(count) |
| } |

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· DeepSeek 开源周回顾「GitHub 热点速览」
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了