[golang gin框架] 7.Gin GORM增删改查以及查询语句详解

这篇文章详细介绍了如何在Gin框架中使用GORM库进行数据库的基本操作,包括添加、查找、修改和删除数据。GORM是一个用于Go语言的ORM库,简化了数据库交互。示例代码展示了如何定义模型、执行查询、条件过滤、排序、分页以及使用预加载等功能。
摘要由CSDN通过智能技术生成

1.GORM CURD

找到要操作数据库表的控制器,然后引入 models 模块

models/user.go

package models

type User struct { // 结构体首字母大写, 和数据库表名对应, 默认访问数据表users, 可以设置访问数据表的方法
    Id  int
    Username string
    Age int
    Email string
    AddTime int // 大驼峰命名
}

//配置数据库操作的表名称
func (User) TableName() string {
    return "user"
}

(1).添加数据

增加成功后会返回刚才增加的记录
//添加数据
func (con UserController) Add(c *gin.Context) {
    user := &models.User{
        Username: "张三",
        Age: 12,
        Email: "test@qq.com",
        AddTime: int(models.GetUnix()),
    }
    err := models.DB.Create(user).Error // 通过数据的指针来创建
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println(user)
    c.String(200, "增加数据成功")
}

更多添加语句见文档:创建 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

(2).查找

func (con UserController) Index(c *gin.Context) {
    //查找全部
    userList := []models.User{}
    //查询所有用户,把结果保存到userList切片中
    models.DB.Find(&userList)
    c.JSON(http.StatusOK, gin.H{
        "result": userList,
    })

    //条件查询
    //查询age大于30的用户
    //查询数据库
    userList := []models.User{}
    models.DB.Where("age > ?", 30).Find(&userList)
    c.JSON(http.StatusOK, gin.H{
        "result": userList,
    })
}

更多查询语句:查询 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

(3).修改

func (con UserController) Edit(c *gin.Context) {
    //查询id等于5的字段
    user := models.User{Id: 5}
    models.DB.Find(&user)
    c.JSON(200, gin.H{
        "user": user,
    })
    //更新所有数据
    user.Username = "你好"
    user.Age = 111
    models.DB.Save(&user)

    //更新单个列
    user1 := models.User{}
    models.DB.Model(&user1).Where("id = ?", 9).Update("username", "大")

    //一般情况的更新
    user2 := models.User{}
    models.DB.Where("id = ?", 1).Find(&user2)
    user2.Username = "好"
    user2.Age = 31
    models.DB.Save(&user2)
}

更多修改的方法参考:更新 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

(4).删除

//删除数据
func (conn UserController) Delete(c *gin.Context) {
    user := models.User{Id: 1}
    models.DB.Delete(&user)

    //删除数据
    user1 := models.User{}
    models.DB.Where("Age = ?", 31).Delete(&user1)
}

更多删除的方法参考:删除 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

2.GORM 查询语句详解

(1).查询全部数据

    //查询全部数据
    list := []models.Nav{}
    //把结果保存到list切片中
    models.DB.Find(&list)
    c.JSON(http.StatusOK, gin.H{
        "result": list,
    })

(2).查询一条数据

    //查询一条数据
    nav := models.Nav{Id: 21}
    models.DB.Find(&nav)
    c.JSON(http.StatusOK, gin.H{
        "result": nav,
    })
    nav1 := models.Nav{}
    models.DB.First(&nav1, "21")
    c.JSON(http.StatusOK, gin.H{
        "result": nav1,
    })

    nav2 := models.Nav{}
    models.DB.Model(models.Nav{Id: 21}).First(&nav2)
    c.JSON(http.StatusOK, gin.H{
        "result": nav2,
    })

(3).Where

=,<,>,<=,>=,!=,IS NOT NULL,IS NULL,BETWEEN AND,NOT BETWEEN AND,IN,OR,AND,NOT,LIKE查询
    查询id>3的数据
    nav := []models.Nav{}
    models.DB.Where("id > ?", 3).Find(&nav)
    c.JSON(http.StatusOK, gin.H{
        "result": nav,
    })
    
    //查询id>3 并且 id < 9 的数据
    nav1 := []models.Nav{}
    models.DB.Where("id > ? and id < ?", 3, 9).Find(&nav1)
    c.JSON(http.StatusOK, gin.H{
        "result": nav1,
    })
    //查询id=3,5,6的数据
    nav2 := []models.Nav{}
    models.DB.Where("id in ?", []int{3, 5, 6}).Find(&nav2)
    c.JSON(http.StatusOK, gin.H{
        "result": nav2,
    })
    
    //查询标题包含 '会'的内容
    nav3 := []models.Nav{}
    models.DB.Where("title like ?", "%会%").Find(&nav3)
    c.JSON(http.StatusOK, gin.H{
        "result": nav3,
    })
    
    //查询id>3 并且 id < 9 的数据,使用between and
    nav4 := []models.Nav{}
    models.DB.Where("id between ? and ?", 3, 9).Find(&nav4)
    c.JSON(http.StatusOK, gin.H{
        "result": nav4,
    })
    //查询id=2或者iD=3的数据
    //方法一
    nav5 := []models.Nav{}
    models.DB.Where("id = ? or id =  ?", 3, 9).Find(&nav5)
    c.JSON(http.StatusOK, gin.H{
        "result": nav5,
    })
    //方法二
    nav6 := []models.Nav{}
    models.DB.Where("id = ?", 2).Or("id = ?", 3).Find(&nav6)
    c.JSON(http.StatusOK, gin.H{
        "result": nav6,
    })

(4).选择字段查询

    //使用select返回指定的字段, 使用结构体时,没有的数据会默认为0或""
    nav7 := []models.Nav{}
    models.DB.Select("title", "id").Where("id = ?", 2).Or("id = ?", 3).Find(&nav7)
    c.JSON(http.StatusOK, gin.H{
        "result": nav7,
    })

(5).排序 Limit 、Offset

    //order排序, limit, Offset
    nav8 := []models.Nav{}
    models.DB.Order("id desc").Find(&nav8)
    c.JSON(http.StatusOK, gin.H{
        "result": nav8,
    })
    
    nav9 := []models.Nav{}
    models.DB.Order("id desc").Limit(3).Find(&nav9)
    c.JSON(http.StatusOK, gin.H{
        "result": nav9,
    })
    //分页
    nav10 := []models.Nav{}
    models.DB.Order("id desc").Offset(2).Limit(3).Find(&nav10)
    c.JSON(http.StatusOK, gin.H{
        "result": nav10,
    })

(6).count计数

    nav11 := []models.Nav{}
    var num int64
    models.DB.Where("id > ? and id < ?", 3, 9).Find(&nav11).Count(&num)
    c.JSON(http.StatusOK, gin.H{
        "result": num,
    })

(7).Distinct

从模型中选择不相同的值
nav := []models.Nav{}
models.DB.Distinct("title").Order("id desc").Find(&nav)
c.JSON(200, gin.H{ 
    "nav": nav,
 })
//SELECT DISTINCT `title` FROM `nav` ORDER BY id desc

(8).Scan

将结果扫描到结构中的方法与我们使用find的方法类似
type Result struct {
    Name string
    Age int
}
var result Result
models.DB.Table("users").Select("name", "age").Where("name = ?", "Antonio").Scan(&result)
// 原生 SQL
models.DB.Raw("SELECT name, age FROM users WHERE name = ?", "Antonio").Scan(&result)
var result []models.User
models.DB.Raw("SELECT * FROM user").Scan(&result)
fmt.Println(result)

(9).Joins

查询内联
type result struct {
  Name  string
  Email string
}

db.Model(&User{}).Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&result{})
// SELECT users.name, emails.email FROM `users` left join emails on emails.user_id = users.id

rows, err := db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Rows()
for rows.Next() {
  ...
}

db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)

// multiple joins with parameter
db.Joins("JOIN emails ON emails.user_id = users.id AND emails.email = ?", "jinzhu@example.org").Joins("JOIN credit_cards ON credit_cards.user_id = users.id").Where("credit_cards.number = ?", "411111111111").Find(&user)
//Joins 预加载
You can use Joins eager loading associations with a single SQL, for example:

db.Joins("Company").Find(&users)
// SELECT `users`.`id`,`users`.`name`,`users`.`age`,`Company`.`id` AS `Company__id`,`Company`.`name` AS `Company__name` FROM `users` LEFT JOIN `companies` AS `Company` ON `users`.`company_id` = `Company`.`id`;

// inner join
db.InnerJoins("Company").Find(&users)
// SELECT `users`.`id`,`users`.`name`,`users`.`age`,`Company`.`id` AS `Company__id`,`Company`.`name` AS `Company__name` FROM `users` INNER JOIN `companies` AS `Company` ON `users`.`company_id` = `Company`.`id`;
Join with conditions

db.Joins("Company", db.Where(&Company{Alive: true})).Find(&users)
// SELECT `users`.`id`,`users`.`name`,`users`.`age`,`Company`.`id` AS `Company__id`,`Company`.`name` AS `Company__name` FROM `users` LEFT JOIN `companies` AS `Company` ON `users`.`company_id` = `Company`.`id` AND `Company`.`alive` = true;
For more details, please refer to Preloading (Eager Loading).

Joins 一个衍生表
You can also use Joins to join a derived table.

type User struct {
    Id  int
    Age int
}

type Order struct {
    UserId     int
    FinishedAt *time.Time
}

query := db.Table("order").Select("MAX(order.finished_at) as latest").Joins("left join user user on order.user_id = user.id").Where("user.age > ?", 18).Group("order.user_id")
db.Model(&Order{}).Joins("join (?) q on order.finished_at = q.latest", query).Scan(&results)
// SELECT `order`.`user_id`,`order`.`finished_at` FROM `order` join (SELECT MAX(order.finished_at) as latest FROM `order` left join user user on order.user_id = user.id WHERE user.age > 18 GROUP BY `order`.`user_id`) q on order.finished_at = q.latest

(10).查看执行的失去了

package models

//gorm文档: https://gorm.io/zh_CN/docs/index.html
//连接数据库核心代码

import (
    "fmt"
    "gorm.io/gorm"
    "gorm.io/driver/mysql"
)

//全局使用DB,就需要把DB定义成公有的
var DB *gorm.DB
var err error

//自动初始化数据库
func init()  {
    // 参考 https://github.com/go-sql-driver/mysql#dsn-data-source-name 获取详情
    dsn := "root:123456@tcp(127.0.0.1:3306)/gin?charset=utf8mb4&parseTime=True&loc=Local"
    DB, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
    //查看执行的sql
    DB.Debug()
    if err != nil {
        fmt.Println(err)
    }
}

更多查询语句:查询 | GORM - The fantastic ORM library for Golang, aims to be developer friendly.

[上一节]6.Gin GORM简介以及安装

[下一节][golang gin框架] 8.Gin GORM原生 SQL以及表关联查询_gorm获取sql

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以帮您实现这个功能。首先,我需要确认一下您的开发环境是否已经准备好了,包括 Go 编译器和相关的依赖库。 接下来,我将为您提供一个简单的代码示例,用于创建一个 API 服务并实现用户信息的增删改查功能。同时,该示例还包含了图片上传的功能,使用了 Gin 框架GORM ORM 库。 以下是示例代码: ```go package main import ( "fmt" "net/http" "os" "github.com/gin-gonic/gin" "github.com/jinzhu/gorm" _ "github.com/jinzhu/gorm/dialects/mysql" ) type User struct { gorm.Model Name string `json:"name"` Gender string `json:"gender"` Description string `json:"description"` Avatar string `json:"avatar"` } func main() { // 初始化数据库连接 db, err := gorm.Open("mysql", "user:password@tcp(127.0.0.1:3306)/database?charset=utf8mb4&parseTime=True&loc=Local") if err != nil { fmt.Println("database connect error:", err) os.Exit(1) } defer db.Close() // 创建用户表 db.AutoMigrate(&User{}) // 创建 Gin 实例 router := gin.Default() // 添加用户接口 router.POST("/users", func(c *gin.Context) { // 解析请求参数 var user User if err := c.BindJSON(&user); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 保存用户信息 if err := db.Create(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, user) }) // 查询用户接口 router.GET("/users/:id", func(c *gin.Context) { // 获取用户 ID id := c.Param("id") // 查询用户信息 var user User if err := db.First(&user, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, user) }) // 更新用户接口 router.PUT("/users/:id", func(c *gin.Context) { // 获取用户 ID id := c.Param("id") // 查询用户信息 var user User if err := db.First(&user, id).Error; err != nil { c.JSON(http.StatusNotFound, gin.H{"error": err.Error()}) return } // 解析请求参数 var updateUser User if err := c.BindJSON(&updateUser); err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 更新用户信息 user.Name = updateUser.Name user.Gender = updateUser.Gender user.Description = updateUser.Description user.Avatar = updateUser.Avatar if err := db.Save(&user).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, user) }) // 删除用户接口 router.DELETE("/users/:id", func(c *gin.Context) { // 获取用户 ID id := c.Param("id") // 删除用户信息 if err := db.Delete(&User{}, id).Error; err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"message": "delete success"}) }) // 上传图片接口 router.POST("/upload", func(c *gin.Context) { // 从请求中获取文件 file, err := c.FormFile("file") if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } // 保存文件到本地 filename := fmt.Sprintf("uploads/%s", file.Filename) if err := c.SaveUploadedFile(file, filename); err != nil { c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()}) return } c.JSON(http.StatusOK, gin.H{"url": filename}) }) // 启动服务 router.Run(":8080") } ``` 在这个示例中,我们首先定义了一个 User 结构体,包含了我们要存储的用户信息。然后,我们使用 GORM 库创建了一个数据库连接,并在其中创建了一个用户表。 接着,我们使用 Gin 框架创建了四个 API 接口,分别用于添加、查询、更新和删除用户信息。其中,添加、更新和查询用户信息的接口都使用了 BindJSON 方法来解析请求参数,并使用 GORM 库来持久化用户信息到数据库中。 最后,我们还添加了一个用于上传图片的接口,使用了 Gin 框架的 FormFile 方法来获取上传的文件,并使用 SaveUploadedFile 方法将文件保存到本地。 请注意,由于这个示例中的数据库连接字符串中包含了敏感信息,因此在实际使用中,您需要将其替换为您自己的数据库连接字符串。 希望这个示例能够帮助到您,如果您有任何问题或需要进一步的帮助,请随时提出。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值