使用 GORM连接数据库

199 阅读3分钟

GORM 是 Go 语言中流行的对象关系映射(ORM)库,提供了简洁且强大的数据库操作功能,使开发者可以更轻松地与数据库进行交互。

本文将以 MySQL 为例,详细介绍如何使用 GORM 连接数据库,并实现增、删、改、查操作。本文将从安装 GORM 开始,到如何定义模型、自动迁移数据表,以及执行数据库操作的完整流程。


安装GORM 和数据库驱动

首先,确保你已经安装了 Go 开发环境和 MySQL 数据库。

// 安装gorm
go get -u gorm.io/gorm 
// 安装mysql驱动
go get -u gorm.io/driver/mysql

创建数据库

CREATE DATABASE dbname;

连接到数据库

package main

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

func main() {
    dsn := "username: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("无法连接到数据库: " + err.Error())
    }
}

其中, usernamepassworddbname 可替换为自己的数据库用户名、密码和数据库名称。


模型的定义

模型是使用普通结构体定义的。这些结构体可以包含具有基本 Go 类型的字段、指针或这些类型的别名,甚至是自定义类型,只要它们实现了包中的 Scanner 和 Valuer 接口。

模型定义与自动迁移

在 GORM 中,模型使用结构体来定义,并映射到数据库中的表。本文以 Student 模型为例:

type Student struct {
    ID   uint   `gorm:"primaryKey"`  //指定主键
    Name string
    Age  int
}

自动迁移: 可以根据模型自动创建或更新数据库表结构:

db.AutoMigrate(&Student{})

增、删、改、查操作

创建

通过Create方法,实现对新增操作

func createStudent(name sring, age int ,db *gorm.DB) {
        s := User{Name: name, Age: age}
        result := db.Create(&s)  // 插入数据
        
        fmt.Println(s.ID) //插入数据后,返回主键值
        result.Error  //返回错误信息
}
用指定字段创建
func createStudentByName(name string, db *gorm.DB) {
    s := Student{Name: name}
    db.Select("Name").Create(&s) // 为指定字段进行赋值并创建
}
批量创建

批量插入可通过切片传递给Create方法,GORM会自动生成sql语句对这些数据进行插入。

func createStudents(students []Student, db *gorm.DB) {
    db.Create(&students) // 批量插入
}

查询

GORM 提供了 FirstTakeLast 方法,以便从数据库中检索单个对象。下面通过First方法通过ID查询:

func getStudentByID(id uint, db *gorm.DB) {
    var s Student
    result := db.First(&s, id) // 按 ID 查询
    
    fmt.Printf("查询到用户: %+v\n", s)
    
    result.Error
}
批量查询

Find() 是用于执行数据库查询并将结果映射到结构体或结构体切片中的方法,它通常用于检索多条记录。

func getStudentsByIDs(ids []uint, db *gorm.DB) {
    var students []Student
    result := db.Find(&students, ids) // 根据 ID 列表查询
    
    result.RowsAffected //返回找到的记录数
    result.Error
}

更新

Save 方法会保存所有的字段。如果记录不存在,它会插入新记录;如果记录存在,它会更新记录。

func updateStudentAge(id uint, newAge int, db *gorm.DB) {
    var s Student
    result := db.First(&s, id) // 查找用户

    s.Age = newAge
    db.Save(&s) // 更新用户信息
    fmt.Println("学生信息更新成功")
}

删除

Delete() 方法用于从数据库中删除记录。
GORM 默认使用软删除,即并不会物理删除数据,而是设置一个删除标志。

func deleteStudent(id uint, db *gorm.DB) {
    result := db.Delete(&Student{}, id) // 按 ID 删除

    if result.Error != nil {
       fmt.Println("删除失败:", result.Error)
       return
    }

    fmt.Println("删除成功")
}
批量删除
func deleteStudentsByIDs(ids []uint, db *gorm.DB) {
    result := db.Delete(&Student{}, ids) // 根据 ID 列表删除

    fmt.Println("批量删除成功")
}
软删除和硬删除
  • 软删除:需要在模型中添加 gorm.ModelDeletedAt 字段。

  • 硬删除: 如果要执行物理删除,可以使用 Unscoped() 方法:

 db.Unscoped().Delete(&student)      // 永久删除记录

完整代码

package main

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

type Student struct {
    ID   uint `gorm:"primary_key"`
    Name string
    Age  int
}

func main() {
    dsn := "root:123456@(localhost)/gormdb?charset=utf8mb4&parseTime=True&loc=Local"
    db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

    if err != nil {
       panic(err)
    }

    //新增 学生
    createStudent("wangwu", 18, db)

    //查找id:1的学生
    getStudentByID(1, db)

    // 更新id:1的年龄为20
    updateStudentAge(1, 20, db)

    //删除 id:3 的学生
    deleteStudent(3, db)
    
    /* 可调用其他方法测试 */
}

func createStudent(name string, age int, db *gorm.DB) {/**/}

func createStudents(students []Student, db *gorm.DB) {/**/}

func getStudentByID(id uint, db *gorm.DB) {/**/}

func getStudentsByIDs(ids []uint, db *gorm.DB) {/**/}

func updateStudentAge(id uint, newAge int, db *gorm.DB) {/**/}

func deleteStudent(id uint, db *gorm.DB) {/**/}

func deleteStudentsByIDs(ids []uint, db *gorm.DB) {/**/}