3.2.1GoWeb框架GORM

GORM 除了提供基本的 CRUD 操作,还支持多种高级查询功能,能够帮助你更灵活地从数据库中检索数据

1. 条件查询

可以使用 Where 方法根据不同条件筛选数据。

基本条件查询
package main

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

type User struct {
    gorm.Model
    Name  string
    Age   int
    Email string
}

func main() {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        panic("failed to connect database")
    }

    var users []User
    // 查询年龄大于 20 的用户
    db.Where("age > ?", 20).Find(&users)
    for _, user := range users {
        fmt.Printf("Name: %s, Age: %d\n", user.Name, user.Age)
    }
}
多条件查询
// 查询年龄大于 20 且名字为 John 的用户
db.Where("age > ? AND name = ?", 20, "John").Find(&users)
模糊查询
// 查询名字中包含 "Doe" 的用户
db.Where("name LIKE ?", "%Doe%").Find(&users)

2. 排序查询

使用 Order 方法对查询结果进行排序。

// 按年龄升序排序
db.Order("age ASC").Find(&users)

// 按年龄降序排序
db.Order("age DESC").Find(&users)

3. 分页查询

通过 Limit 和 Offset 方法实现分页查询。

// 每页 10 条记录,查询第 2 页的数据
page := 2
pageSize := 10
offset := (page - 1) * pageSize
db.Limit(pageSize).Offset(offset).Find(&users)

4. 分组查询

使用 Group 方法进行分组,结合 Having 方法进行分组过滤。

type Result struct {
    Age  int
    Count int
}

var results []Result
// 按年龄分组并统计每组的用户数量
db.Model(&User{}).Select("age, count(*) as count").Group("age").Find(&results)

// 只返回用户数量大于 2 的分组
db.Model(&User{}).Select("age, count(*) as count").Group("age").Having("count > 2").Find(&results)

5. 关联查询

预加载关联数据

使用 Preload 方法在查询主模型时同时加载关联的模型数据,避免 N + 1 查询问题。

type User struct {
    gorm.Model
    Name  string
    Posts []Post
}

type Post struct {
    gorm.Model
    Title  string
    UserID uint
}

// 查询用户及其帖子
var user User
db.Preload("Posts").First(&user, 1)
关联条件查询
// 查询有帖子标题包含 "GORM" 的用户
db.Where("exists (select 1 from posts where posts.user_id = users.id and posts.title like ?)", "%GORM%").Find(&users)

6. 子查询

// 子查询示例:查询年龄大于平均年龄的用户
subQuery := db.Model(&User{}).Select("AVG(age)")
db.Where("age > (?)", subQuery).Find(&users)

7. 原生 SQL 查询

在某些复杂场景下,可以使用 Raw 方法执行原生 SQL 查询。

var users []User
db.Raw("SELECT * FROM users WHERE age > ?", 20).Scan(&users)

在gin中使用GORM

在 Go 语言中,Gin 是一个轻量级的 Web 框架,而 GORM 是与之搭配较为理想的 ORM(对象关系映射)框架,和 Gin 配合可以高效地构建 Web 应用。

连接数据库

创建一个数据库连接文件,用于初始化 GORM 连接到 MySQL 数据库。

请将userpassworddbname替换为你自己的数据库用户名、密码和数据库名。

定义模型

创建一个模型文件,定义数据库表对应的 Go 结构体。

创建 Gin 路由和控制器

创建一个 Gin 路由文件,处理 HTTP 请求,并使用 GORM 进行数据库操作。

package main

import (
    "log"
    "net/http"

    "github.com/gin-gonic/gin"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
)

// 全局数据库连接变量
var db *gorm.DB

// 数据库连接配置
func ConnectDB() error {
    dsn := "user:password@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"
    var err error
    db, err = gorm.Open(mysql.Open(dsn), &gorm.Config{})
    if err != nil {
        return err
    }
    return nil
}

// 用户模型
type User struct {
    gorm.Model
    Name     string
    Email    string `gorm:"unique"`
    Password string
}

// 初始化路由
func SetupRouter() *gin.Engine {
    r := gin.Default()

    err := ConnectDB()
    if err != nil {
        log.Fatal("failed to connect database")
    }

    // 自动迁移模型
    db.AutoMigrate(&User{})

    // 定义路由组
    api := r.Group("/api")
    {
        users := api.Group("/users")
        {
            users.GET("", GetUsers)
            users.GET("/:id", GetUser)
            users.POST("", CreateUser)
            users.PUT("/:id", UpdateUser)
            users.DELETE("/:id", DeleteUser)
        }
    }

    return r
}

// GetUsers 获取所有用户
func GetUsers(c *gin.Context) {
    var users []User
    db.Find(&users)
    c.JSON(http.StatusOK, users)
}

// GetUser 获取单个用户
func GetUser(c *gin.Context) {
    var user User
    id := c.Param("id")
    if err := db.First(&user, id).Error; err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
        return
    }
    c.JSON(http.StatusOK, user)
}

// CreateUser 创建用户
func CreateUser(c *gin.Context) {
    var user User
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    if err := db.Create(&user).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to create user"})
        return
    }
    c.JSON(http.StatusCreated, user)
}

// UpdateUser 更新用户
func UpdateUser(c *gin.Context) {
    var user User
    id := c.Param("id")
    if err := db.First(&user, id).Error; err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
        return
    }
    if err := c.ShouldBindJSON(&user); err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
        return
    }
    if err := db.Save(&user).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to update user"})
        return
    }
    c.JSON(http.StatusOK, user)
}

// DeleteUser 删除用户
func DeleteUser(c *gin.Context) {
    var user User
    id := c.Param("id")
    if err := db.First(&user, id).Error; err != nil {
        c.JSON(http.StatusNotFound, gin.H{"error": "User not found"})
        return
    }
    if err := db.Delete(&user).Error; err != nil {
        c.JSON(http.StatusBadRequest, gin.H{"error": "Failed to delete user"})
        return
    }
    c.JSON(http.StatusNoContent, nil)
}

func main() {
    r := SetupRouter()
    r.Run(":8080")
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chxii

小小打赏,大大鼓励!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值