首页 > 其他分享 >go语言Gin框架的学习路线(九)

go语言Gin框架的学习路线(九)

时间:2024-07-22 23:55:26浏览次数:15  
标签:框架 记录 创建 数据库 GORM User go Gin gorm

GORM的CRUD教程

CRUD 是 "Create, Read, Update, Delete"(创建、读取、更新、删除)的缩写,代表了数据库操作的基本功能。在 GORM 的上下文中,CRUD 指的是使用 GORM 库来执行这些基本的数据库操作。

创建的

在 GORM 中创建记录通常使用 Create 方法。以下是一个创建记录的例子,包括定义模型、创建记录以及处理数据库连接:

步骤 1: 定义模型

首先,定义一个模型,通常是一个结构体,它内嵌了 GORM 的 Model 结构体来获得自动管理的字段,如 IDCreatedAtUpdatedAt 等。

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

步骤 2: 连接数据库

然后,使用 GORM 连接到数据库。这里以 SQLite 为例,实际使用中可以是 MySQL、PostgreSQL、SQL Server 等。

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
    "log"
)

func main() {
    dsn := "file:db.sqlite?mode=memory&cache=shared&_fk=1"
    db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatal("Could not connect to the database", err)
    }
    defer db.Close()

步骤 3: 自动迁移

使用 AutoMigrate 方法来自动创建或更新数据库表,以匹配模型的结构。

// 自动迁移模式,确保数据库结构与 User 结构体一致
db.AutoMigrate(&User{})

步骤 4: 创建记录

使用 Create 方法创建新的记录。

    // 创建新用户
    user := User{Name: "Alice", Age: 30, Email: "[email protected]"}
    db.Create(&user) // 使用 &user 因为 Create 需要指针来设置返回值
}

在这个例子中,Create 方法将 User 结构体的实例插入到数据库中。CreatedAt 字段会自动设置为当前时间戳,表示记录被创建的时间。如果记录成功创建,user 变量也会被更新,包括数据库生成的主键 ID

完整示例代码
package main

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
    "log"
)

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

func main() {
    dsn := "file:db.sqlite?mode=memory&cache=shared&_fk=1"
    db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatal("Could not connect to the database", err)
    }
    defer db.Close()

    db.AutoMigrate(&User{})

    user := User{Name: "Alice", Age: 30, Email: "[email protected]"}
    db.Create(&user) // 注意 Create 方法需要一个指针

    // 打印创建的用户信息
    log.Printf("Created User: %+v\n", user)
}

这个示例程序展示了如何使用 GORM 来定义一个模型、连接到数据库、自动创建表结构、插入一条新记录,并打印这条记录。这整个过程就是数据库操作中的 "Create"(创建)部分。通过 GORM,你可以用面向对象的方式来处理数据库的 CRUD 操作,而不需要编写复杂的 SQL 语句。

在 GORM 中,创建记录时可以结合多种方式来设置默认值。

以下是一些方法和示例,展示如何在创建记录时使用这些功能:

1. 使用 Tag 定义字段的默认值

你可以在结构体字段的 tag 中使用 default 关键字来指定默认值。

type User struct {
    gorm.Model
    Name    string
    Age     int    `gorm:"default:30"`
    Email   string `gorm:"default:'[email protected]'"`
}

在这个例子中,如果创建 User 时没有指定 AgeEmail,它们将自动被设置为 30'[email protected]'

GORM 的 tag 允许你为字段指定额外的选项,这些选项在数据库迁移、记录创建和查询时会被 GORM 识别和使用。在这个例子中,default 关键字用于指定字段的默认值。 

2. 使用指针方式实现零值存入数据库

通过使用指针类型,你可以在创建记录时将某些字段设置为 SQL 的 NULL 值。

type User struct {
    gorm.Model
    Name string
    Bio  *string
}

如果 Bionil,它在数据库中将被存储为 NULL。

  • Bio: 一个指向字符串的指针 *string。这里的指针用法有几个目的:

    • NULL 值: 在 SQL 中,指针可以用来表示 NULL 值。如果 Bio 被初始化为 nil,那么在数据库中对应的字段将存储为 NULL。
    • 可选字段: 指针表示这个字段是可选的,不是必须的。只有当 Bio 被赋予了一个非 nil 的值时,才会在数据库中存储一个实际的字符串。
    • 空字符串与 NULL 的区分: 如果字段是 *string 类型,你可以区分空字符串 ("") 和 NULL。空字符串是一个有效的字符串值,而 NULL 表示字段没有值。

3. 使用 Scanner/Valuer 接口方式实现零值存入数据库

通过实现 sql.Scannerdriver.Valuer 接口,你可以控制字段的默认行为。

type CustomType struct {
    value string
}

func (ct *CustomType) Scan(src interface{}) error {
    var str string
    err := sql.Scan(src, &str)
    if err != nil {
        return err
    }
    ct.value = str
    return nil
}

func (ct CustomType) Value() (driver.Value, error) {
    if ct.value == "" {
        return "default_value", nil // 返回默认值
    }
    return ct.value, nil
}

type User struct {
    gorm.Model
    Name string
    Data CustomType `gorm:"not null"`
}

在这个例子中,如果 Data.value 是空字符串,Value() 方法将返回 "default_value" 作为默认值。

代码理解

  • CustomType 的 Scan 方法允许你在从数据库检索记录时自定义如何将数据库中的值(通常是字符串)转换为 CustomType 类型的字段。
  • CustomType 的 Value 方法允许你在将记录保存到数据库时自定义如何将 CustomType 类型的字段转换为数据库中的值。在这个例子中,如果 value 是空字符串,它将使用 "default_value" 作为默认值。
  • User 结构体中的 Data 字段使用 CustomType,这意味着在数据库操作中,Data 字段的值将通过 CustomType 的 Scan 和 Value 方法进行转换。
  • gorm:"not null" tag 指示 GORM 在数据库中对应的列不允许为空值。如果使用 Data 作为字段类型,你需要确保在调用 Value 方法时总是返回一个非 NULL 的数据库值。

示例应用

这个自定义类型和接口实现可以用于处理那些需要特殊处理的数据库字段,例如,加密字段、格式特定的字段,或者像这里的示例,当数据库字段可能为空但你想提供一个默认值的情况。

4. 扩展创建选项

你可以使用 Create 方法的选项来自定义创建行为,例如设置默认值。

user := User{Name: "Alice"}
db.Clauses(clause.Expr{SQL: "SET", Name: "age", Value: 30}).Create(&user)

在这个例子中,Clauses 方法用于添加额外的 SQL 表达式,这里使用了 SET 来在创建记录时设置 age 字段的默认值。

5. 使用钩子(Hooks)

GORM 提供了钩子(如 BeforeCreate),在创建记录之前可以设置默认值。

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

func (u *User) BeforeCreate(tx *gorm.DB) error {
    if u.Age == 0 {
        u.Age = 30 // 如果 Age 是 0,设置默认值
    }
    return nil
}

在这个例子中,BeforeCreate 钩子会在记录被创建之前被调用,允许你在记录保存到数据库之前修改字段值。

  • BeforeCreate 是一个在 GORM 创建记录之前自动调用的方法。它是一个钩子,允许你在记录被保存到数据库之前执行自定义逻辑。
  • 这个方法接收一个 *gorm.DB 类型的参数 tx,表示当前的数据库事务。
  • 在这个钩子中,如果 User 的 Age 字段值为 0,它将 Age 设置为 30 作为默认值。
  • 钩子函数返回 nil 表示没有错误,允许 GORM 继续执行创建记录的操作。

钩子的工作流程

  1. 当你调用 db.Create(&user) 来创建一个新的 User 记录时,GORM 会触发 BeforeCreate 钩子。
  2. 在 BeforeCreate 钩子中,你可以访问和修改 user 的字段,例如在这里检查 Age 是否为 0 并设置默认值。
  3. 钩子函数执行完毕后,GORM 会根据修改后的 user 字段的值创建数据库记录。

示例应用

这个钩子非常有用,特别是当你需要在记录保存到数据库之前执行一些验证、计算或设置默认值时。通过使用钩子,你可以保持你的业务逻辑和数据访问代码分离,同时确保数据的一致性和完整性。

注意

  • 钩子函数应该总是返回 nil 错误,除非你想要阻止 GORM 继续执行创建操作。
  • 钩子函数提供了对当前事务的引用,这意味着你可以在钩子中执行额外的数据库操作,例如查询或更新其他记录。

通过这种方式,GORM 的钩子提供了一个强大的机制来自定义数据库操作流程。

在 GORM 中,钩子(Hooks)的作用是在特定的数据库操作事件之前或之后自动执行代码。这些钩子可以视为拦截器或回调函数,它们允许你在 GORM 执行标准 CRUD 操作的过程中插入自定义逻辑。

钩子的主要作用包括:

  1. 设置默认值

    • 在创建或更新记录之前,可以设置字段的默认值。
  2. 验证数据

    • 在创建或更新记录之前,可以验证数据的有效性,如果数据不符合要求,可以返回错误以中断操作。
  3. 修改字段值

    • 在记录保存到数据库之前,可以修改字段的值,例如,对密码进行加密处理。
  4. 执行额外的数据库操作

    • 可以在创建或更新记录的同时,执行其他数据库操作,如更新相关联的记录或触发级联删除。
  5. 记录操作日志

    • 可以在记录被创建或更新后,记录操作日志,用于审计或调试。
  6. 处理关联关系

    • 在创建或更新具有关联关系(如外键)的记录时,可以手动处理这些关系。
  7. 自动填充字段

    • 可以在记录创建或更新后,自动填充某些字段,如根据当前时间自动设置时间戳。
  8. 事务管理

    • 可以在钩子中执行事务的提交或回滚操作,以确保数据的一致性。

可用的钩子类型:

  • BeforeCreate(): 在记录创建之前调用。
  • AfterCreate(): 在记录创建之后调用。
  • BeforeSave(): 在记录保存之前调用,适用于创建和更新操作。
  • AfterSave(): 在记录保存之后调用,适用于创建和更新操作。
  • BeforeUpdate(): 在记录更新之前调用。
  • AfterUpdate(): 在记录更新之后调用。
  • BeforeDelete(): 在记录删除之前调用。
  • AfterDelete(): 在记录删除之后调用。
  • BeforeFind(): 在记录查询之前调用。
  • AfterFind(): 在记录查询之后调用。

示例代码

结合以上方法,以下是一个完整的示例,展示如何在创建记录时使用这些功能:

package main

import (
    "gorm.io/driver/sqlite"
    "gorm.io/gorm"
    "log"
    "time"
)

type CustomType struct {
    value string
}

func (ct *CustomType) Scan(src interface{}) error {
    var str string
    err := sql.Scan(src, &str)
    if err != nil {
        return err
    }
    ct.value = str
    return nil
}

func (ct CustomType) Value() (driver.Value, error) {
    if ct.value == "" {
        return "default_value", nil // 返回默认值
    }
    return ct.value, nil
}

type User struct {
    gorm.Model
    Name    string
    Age     int           `gorm:"default:30"`
    Bio     *string
    Data    CustomType    `gorm:"not null"`
}

func (u *User) BeforeCreate(tx *gorm.DB) error {
    if u.Age == 0 {
        u.Age = 30 // 如果 Age 是 0,设置默认值
    }
    if u.Bio == nil {
        u.Bio = new(string)
        *u.Bio = "This is a bio"
    }
    return nil
}

func main() {
    dsn := "file:db.sqlite?mode=memory&cache=shared&_fk=1"
    db, err := gorm.Open(sqlite.Open(dsn), &gorm.Config{})
    if err != nil {
        log.Fatal("Could not connect to the database", err)
    }
    defer db.Close()

    db.AutoMigrate(&User{})

    user := User{Name: "Alice", Bio: nil}
    db.Create(&user)

    var createdUser User
    db.First(&createdUser, "name = ?", "Alice")
    log.Printf("Created User: %+v\n", createdUser)
}

 期末放假自学Gin框架,希望我们可以一起学习!

标签:框架,记录,创建,数据库,GORM,User,go,Gin,gorm
From: https://blog.csdn.net/juzihuaile/article/details/140621927

相关文章

  • go语言Gin框架的学习路线(八)
    目录GORMModel定义使用 Model 结构体的自定义数据模型理解并记忆GORM的Model结构体可以通过以下几个步骤和技巧:1. 理解基本概念2. 熟悉基本字段3. 记忆技巧4. 使用场景结构体标记支持的结构体标记(Structtags)关联相关标记(tags)GROM(默认行为)主键、表名的......
  • vue项目打包以及在nginx中部署
    ——————vue项目打包点击npm脚本下的build中的三角即可没有npm脚本的话点下package.json,还没有的参考博客https://www.cnblogs.com/yansans/p/18303172 稍微等一会,打包完成后数据会放在新生成的dist目录中  打包结束  ——————在nginx中部署在文件夹......
  • 接口自动化测试框架实战-0-项目功能概览
    熟悉我CSDN的朋友们应该知道,之前已经更新了requests、pytest、allure2、yaml、jenkins、postman等基础知识的合集。相信大家对接口测试已经有了全面的认识,现在应该迫不及待地想要一个实战项目了。接下来的文章中,我们将把这些知识点串联起来,以钉钉开放接口为例,一起从0到1开发一......
  • Django 入门指南:从环境设置到创建第一个应用程序
    简介Django是一个流行的PythonWeb框架,用于快速开发强大的Web应用程序。本指南将带你从安装Django开始,逐步学习如何创建一个简单的Django项目和应用程序。步骤1:准备环境首先,确保你的开发环境中安装了Python,并了解如何使用虚拟环境来管理项目依赖。安装虚拟......
  • 登陆京东(滑块验证),验证码识别,Scrapy框架介绍及其使用,持久化存储到本地
    Ⅰ案例登陆京东(滑块验证)【一】下载opencv库pipinstallopencv-python【二】数据准备先将京东的滑块图片下载到本地背景图background.png滑块图tag.png【三】展示获取滑块的移动数据importos.path#使用opencv识别图像计算滑块之间的距离importcv2impo......
  • keepalived+nginx实现负载均衡
    1、安装keepalived(源码编译安装)wgethttps://www.keepalived.org/software/keepalived-2.3.0.tar.gztar-zxfkeepalived-2.3.0.tar.gzcdkeepalived-2.3.0&&  mkdir/data01/keepalived&& ./configure--prefix=/data01/keepalived&&make-j4&&......
  • AtCoder Beginner Contest 363
    AtCoderBeginnerContest363PilingUp模拟题。点击查看代码#include<bits/stdc++.h>usingnamespacestd;inta;signedmain(){cin>>a;if(a%100!=0){a%=100;cout<<100-a;}else{cout<<100;}retur......
  • MySQL Architecture And Engine
    Author:ACatSmilingSince:2024-07-22SELECT的执行过程SELECT的查询结构方式一:SELECT...,...,...FROM...,...,...WHERE多表的连接条件AND不包含组函数的过滤条件GROUPBY...,...HAVING包含组函数的过滤条件ORDERBY...ASC/DESCLIMIT...,...;方式二......
  • 【Golang 面试基础题】每日 5 题(三)
    ✍个人博客:Pandaconda-CSDN博客......
  • Prompt Enginnering(提示工程)
    什么是提示工程promptenginnering是提示工程的意思,也有叫指令工程。用白话讲:是我们对GPT说出的话,我们向它提问的信息,就是prompt。官方一点:是我们使用自然语言提示来控制和优化生成式模型(生成式模型例如:OpenAi的GPT-3,GPT-4o)输出的一项技术。对prompt进行优化,可以使我们从生......