美文网首页
grom-V2-04-高级查询

grom-V2-04-高级查询

作者: 玄德公笔记 | 来源:发表于2022-02-14 23:23 被阅读0次

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)
// SELECT * FROM "users" WHERE age > (SELECT AVG(age) FROM "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() 迭代

  • 使用
    用Rows() 记录数据 ----> rows.Next()逐行读出-----> 用ScanRows赋值给结构体

  • 示例

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
        // ScanRows 方法用于将一行记录扫描至结构体
        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)
}

相关文章

  • grom-V2-04-高级查询

    1. 用Struct或Map接收数据 1.1 Find到Struct 定义一个小的结构体来接收表中的查询结果 完整...

  • 高级查询

    SQL语句的强化求所有电脑产品的平均价格,并且保留两位小数:select round(avg(price),2) ...

  • 高级查询

    分组函数 使用方法: MIN和MAX函数:返回每组的最小或最大值 可用于任何数据类型 应用: SUM和AVG函数:...

  • 高级查询

    -5个分组函数 where 中不可以有别名,where中不能有分组函数-- 组后条件 select 语句执行过程 ...

  • 高级查询

    数据库示例: 学生信息表student 成绩表score 一、子查询 一个内层查询语句(select-from-w...

  • 高级查询

    分页和过滤查询 流程图 : 前面我们已经讲过分页查询了 , 接下来我们讲讲 过滤查询 . 思路 : 从后台开始写 ...

  • GreenDao集成教程(三) DB高级查询

    高级查询 DEMO入口

  • SQL查询_高级查询

    SQL查询_高级查询 一、子查询 子查询出现的位置一般为条件语句,oracle会先执行子查询,再执行父查询,子查询...

  • spring date mongo mongotemplate使

    Spring数据MongoDB三:基本文档查询(查询,基本查询)(一) MongoDB高级查询[聚合] sprin...

  • Hive高级查询

    Hive高级查询 查询操作group by、Order by 、Join 、distribute by 、Sort...

网友评论

      本文标题:grom-V2-04-高级查询

      本文链接:https://www.haomeiwen.com/subject/muutlrtx.html