首页 > 其他分享 >GORM高级查询

GORM高级查询

时间:2024-01-23 15:14:54浏览次数:23  
标签:name fmt DB 高级 查询 age stud GORM Find

GORM高级查询

准备数据

type Student struct {
  ID     uint   `gorm:"size:3"`
  Name   string `gorm:"size:8"`
  Age    int    `gorm:"size:3"`
  Gender bool
  Email  *string `gorm:"size:32"`
}

func (stu Student) TableName() string {
	return "student"
}

func main(){
  var studentList []Student
  DB.Find(&studentList).Delete(&studentList)
  studentList = []Student{
    {ID: 1, Name: "李元芳", Age: 32, Email: PtrString("[email protected]"), Gender: true},
    {ID: 2, Name: "张武", Age: 18, Email: PtrString("[email protected]"), Gender: true},
    {ID: 3, Name: "枫枫", Age: 23, Email: PtrString("[email protected]"), Gender: true},
    {ID: 4, Name: "刘大", Age: 54, Email: PtrString("[email protected]"), Gender: true},
    {ID: 5, Name: "李武", Age: 23, Email: PtrString("[email protected]"), Gender: true},
    {ID: 6, Name: "李琦", Age: 14, Email: PtrString("[email protected]"), Gender: false},
    {ID: 7, Name: "晓梅", Age: 25, Email: PtrString("[email protected]"), Gender: false},
    {ID: 8, Name: "如燕", Age: 26, Email: PtrString("[email protected]"), Gender: false},
    {ID: 9, Name: "魔灵", Age: 21, Email: PtrString("[email protected]"), Gender: true},
  }
  DB.Create(&studentList)
}

func PtrString(email string) *string {
  return &email
}

Where

	stud := []Student{}
	// 查询用户名是枫枫的
	DB.Where("name = ?", "枫枫").Find(&stud)
	fmt.Printf("%v\n", stud)
	//fmt.Printf("%v\n", *stud[0].Email)

	// 查询用户名不是枫枫的
	DB.Where("not name = ?", "枫枫").Find(&stud)
	fmt.Printf("%v\n", stud)
	//for _, v := range stud {
	//	fmt.Println(*v.Email)
	//}

	// 查询用户名包含 如燕,李元芳的
	DB.Where("name in ?", []string{"如燕", "李元芳"}).Find(&stud)
	fmt.Printf("%v\n", stud)
	// 查询姓李的
	DB.Where("name like ?", "李%").Find(&stud)
	fmt.Printf("%v\n", stud)

	// 查询年龄大于23,是qq邮箱的
	DB.Where("age > ? and email like ?", 23, "%@qq.com").Find(&stud)
	fmt.Printf("%v\n", stud)

	// 查询是qq邮箱的,或者是女的
	DB.Where("email like ? or gender = ?", "@qq.com", false).Find(&stud)
	fmt.Printf("%v\n", stud)

使用结构体查询

使用结构体查询,会过滤零值

并且结构体中的条件都是and关系

// 会过滤零值
DB.Where(&Student{Name: "李元芳", Age: 0}).Find(&users)
fmt.Println(users)

/*
	SELECT * FROM `student` WHERE `student`.`name` = '李元芳'
	age=0的条件不生效
*/

使用map查询

不会过滤零值

DB.Where(map[string]any{"name": "李元芳", "age": 0}).Find(&users)
// SELECT * FROM `student` WHERE `age` = 0 AND `name` = '李元芳
fmt.Println(users)CopyErrorOK!

Not条件

和where中的not等价

// 排除年龄大于23的
DB.Not("age > 23").Find(&users)
fmt.Println(users)CopyErrorOK!

Or条件

和where中的or等价

stud := []Student{}
DB.Or("gender = ?", false).Or(" email like ?", "%@qq.com").Find(&users)
fmt.Println(users)

Select选择字段

stud := []Student{}
DB.Select("name", "age").Find(&users)
fmt.Println(users)
// 没有被选中,会被赋零值
/*
    SELECT `name` FROM `student`
    [{0 李元芳 0 false <nil>} {0 张武 0 false <nil>} {0 枫枫 0 false <nil>} {0 刘大 0 false <nil>} {0 李武 0 false <nil>} {0 李琦 0 false <nil>} {0 晓梅 0  如燕 0 false <nil>} {0 魔灵 0 false <nil>}]
    只有name字段有值,其余字段都是对应数据类型的默认值
*/

可以使用扫描Scan,将选择的字段存入另一个结构体中

	type User struct {
		Name string
		Age  int
	}
	stud := []Student{}
	userList := []User{}
	DB.Select([]string{"name", "age"}).Find(&stud).Scan(&userList)
	// 指定表名
	DB.Table("student").Select([]string{"name", "age"}).Scan(&userList)
	// Model传入表的对象
	DB.Model(Student{}).Select([]string{"name", "age"}).Scan(&userList)
	fmt.Println(userList)

Scan是根据column列名进行扫描的

type User struct {
  Name123 string `gorm:"column:name"` 
  Age     int
}
stud := []Student{}
DB.Table("students").Select("name", "age").Scan(&stud)
fmt.Println(stud)

排序

根据年龄倒序

stud := []Student{}
DB.Order("age desc").Find(&stud)
fmt.Println(stud)
// desc    降序
// asc     升序

注意order的顺序

分页查询

stud := []Student{}
// 一页两条,第1页
DB.Limit(2).Offset(0).Find(&stud)
fmt.Println(stud)
// 第2页
DB.Limit(2).Offset(2).Find(&stud)
fmt.Println(stud)
// 第3页
DB.Limit(2).Offset(4).Find(&stud)
fmt.Println(stud)

通用写法

stud := []Student{}
// 一页多少条
limit := 2
// 第几页
page := 1
offset := (page - 1) * limit
DB.Limit(limit).Offset(offset).Find(&stud)
fmt.Println(stud)

去重

stud := []Student{}
DB.Table("student").Select("age").Distinct("age").Scan(&stud)
fmt.Println(stud)

或者

DB.Table("student").Select("distinct age").Scan(&stud)

分组查询

var ageList []int
// 查询男生的个数和女生的个数
DB.Table("students").Select("count(id)").Group("gender").Scan(&ageList)
fmt.Println(ageList)
/*
	结果:[6 3]
*/

有个问题,哪一个是男生个数,那个是女生个数

所以我们应该精确一点

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)"`
}

var agge []AggeGroup
// 查询男生的个数和女生的个数
DB.Table("students").Select("count(id)", "gender", "group_concat(name)").Group("gender").Scan(&agge)
fmt.Println(agge)

也可以写成
type AggeGroup struct {
    Gender int
    Count  int
    Name   string
}

var agge []AggeGroup
// 查询男生的个数和女生的个数
DB.Table("student").Select("count(id) as count", "gender", "group_concat(name) as 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);

使用gorm编写

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)
}

标签:name,fmt,DB,高级,查询,age,stud,GORM,Find
From: https://www.cnblogs.com/chunyouqudongwuyuan/p/17982523

相关文章

  • mysql 查询所有表
    MySQL是一种开源的关系型数据库管理系统,在各种Web应用中使用广泛,因为它是高度可定制且易于管理的。MySQL包含一组操作,使您可以创建,更新和查询数据库中的数据。其中一个重要操作是查询所有表的数据,本文将介绍如何实现这一操作。一、使用SHOWTABLES命令SHOWTABLES命令是最简单和......
  • EAS_查询分析器中误删数据恢复
    1、通过flashbackquery查询某历史时点的数据量,找到删除时间点的前1s,如2020-05-1316:38:07秒钟误删的数据:selectcount(*)fromt_testasoftimestampto_timestamp('2020-05-1316:38:06','yyyy-mm-ddhh24:mi:ss');--查出5000条数据,查询6s时的数据select*fro......
  • 数据库学习笔记(三)—— MySQL 之 SELECT(查询)篇
    查询单表查询select分组函数,分组后的字段from表名[where条件][groupby分组的字段][having分组后的筛选][orderby排序列表];排序SELECT字段名FROM表名ORDERBY字段名[ASC|DESC];ASC表示升序,DESC表示降序,而ORDERBY默认值为ASC。多字段排......
  • SqlServer的实用且高级玩法.md
    1.常见表表达式(CTEs)如果您想要查询子查询,那就是CTEs施展身手的时候-CTEs基本上创建了一个临时表。使用常用表表达式(CTEs)是模块化和分解代码的好方法,与您将文章分解为几个段落的方式相同。请在Where子句中使用子查询进行以下查询。1.1在查询中有许多子查询,那么怎么样?这就是C......
  • MySQL回表查询与索引覆盖
    前言  InnoDB引擎中,B+树索引可以分为聚簇索引和辅助索引两大类。在介绍“回表”和“索引覆盖”之前,我们先来了解一下这两个概念。聚簇索引  聚簇索引也叫聚集索引,它并不是一种单独的索引类型,在聚簇索引的叶子页中,保存了整张表的行数据信息,所以也将聚簇索引的叶子节点......
  • Mybatis慢查询问题
    一、问题使用Mybatis查询数据库数据时发现,时间跨度大且数据量多的情况下,查询速度变得十分慢,120s以上然而将sql语句放至数据库中去查询时速度很快,只在10s左右带两个时间条件的情况下,最慢任意一个时间或者不带时间次之二、Mybatis中的sqlselecth.SBDW_ID,h.SBDW,count(dist......
  • js用前缀名查找class或id节点,js模糊查询某个dom节点
     1//参数dom为htmldom节点2//参数key为需模糊查询的名称字段3functionqueryClassNode(dom,key){4letcollectArray=[];5for(leti=0;i<dom.childNodes.length;i++){6//核心点7if(d......
  • 如何查询关键词的KD与搜索量
    随着海外贸易的不断发展,越来越多的小伙伴们从事外贸行业,但是随着面对有限的市场和激烈的竞争,很多从业者往往流量的来源比较单一,那就是付费流量,包括谷歌ads,facebook等一些投流广告。广告的好处是当你付出金钱的时候,很快就可以看到结果,点击、曝光甚至表单、下单等这些信息需要不了几......
  • Go语言核心36讲 11 | 通道的高级玩法
    我们已经讨论过了通道的基本操作以及背后的规则。今天,我再来讲讲通道的高级玩法。首先来说说单向通道。我们在说“通道”的时候指的都是双向通道,即:既可以发也可以收的通道。所谓单向通道就是,只能发不能收,或者只能收不能发的通道。一个通道是双向的,还是单向的是由它的类型字面......
  • 基于SSM的公务用车管理智慧云服务监管平台查询统计
    随着信息互联网购物的飞速发展,一般企业都去创建属于自己的管理系统。本文介绍了公务用车管理智慧云服务监管平台的开发全过程。通过分析企业对于公务用车管理智慧云服务监管平台的需求,创建了一个计算机管理公务用车管理智慧云服务监管平台的方案。文章介绍了公务用车管理智慧云服务......