数据库实践记录 | 青训营

19 阅读4分钟

本文是针对“使用 GORM(Go 的 ORM 库)连接数据库,并实现增删改查操作,把实现过程整理成文章”选题的实践记录。

背景知识:ORM,即对象关系映射(Object Relational Mapping),可以简单理解为将关系型数据库中的数据表映射为编程语言中的具体的数据类型(如struct),而GORM库就是一个使用Go语言实现的且功能非常完善易使用的ORM框架。

以下是GORM提供的一些主要特性和功能的介绍,这些功能使得使用GORM进行数据库操作更加便捷和高效,同时提供了灵活和可扩展的接口,满足开发人员各种需求。

  • 关联:提供了Has One、Has Many、Belongs To、Many To Many等关联关系的支持,方便处理数据库表之间的关系。

    Associations (Has One, Has Many, Belongs To, Many To Many, Polymorphism, Single-table inheritance)

  • 钩子函数:支持在Create、Save、Update、Delete、Find等操作之前或之后执行自定义的钩子函数,方便处理相关逻辑。

    Hooks (Before/After Create/Save/Update/Delete/Find)

  • 预加载和联接:通过Preload和Joins方法可以实现预加载关联数据和进行联接查询,优化查询性能。

    Eager loading with PreloadJoins

  • 事务:支持事务操作,包括嵌套事务、保存点(Save Point)和回滚到指定保存点等功能,确保数据的一致性和完整性。

    Transactions, Nested Transactions, Save Point, RollbackTo to Saved Point

  • 上下文和预编译模式:支持上下文模式和预编译模式,提高执行效率和减少数据库查询次数。

    Context, Prepared Statment Mode, DryRun Mode

  • 批量插入和批量操作:支持批量插入数据、分批查询数据、基于Map的Find/Create操作以及使用SQL表达式和上下文值进行CRUD操作。

    Batch Insert, FindInBatches, Find/Create with Map, CRUD with SQL Expr and Context Valuer

  • SQL构建器:内置SQL构建器,支持Upsert、锁定、优化器/索引/注释提示、命名参数、子查询等功能,方便灵活地构建复杂的SQL查询。

    SQL Builder, Upsert, Locking, Optimizer/Index/Comment Hints, Named Argument, SubQuery

  • 复合主键、索引和约束:支持复合主键的定义和使用,以及索引和约束的创建和管理。

    Composite Primary Key, Indexes, Constraints

  • 自动迁移:提供自动迁移功能,可以根据模型定义自动创建和更新数据库表结构。

    Auto Migrations

  • 日志记录:支持记录运行时的日志,方便调试和排查问题。

    Logger

  • 可扩展的插件API:提供可扩展和灵活的插件API,包括数据库解析器(多数据库、读写分离)和Prometheus等,方便自定义扩展应用。

    Extendable, flexible plugin API: Database Resolver (Multiple Databases, Read/Write Splitting) / Prometheus…

  • 每个功能都带有测试:GORM非常注重质量保证,每个特性都配备了相应的测试,确保稳定性和正确性。

    Every feature comes with tests

  • 开发者友好:GORM提供了简洁、直观的API和文档,使开发人员更加友好,降低学习成本和开发难度。

    Developer Friendly

一、安装GORM库和相应的数据库驱动程序。

在命令行中输入以下命令进行安装:

go get -u gorm.io/gorm
go get -u gorm.io/driver/mysql    #mysql可替换为其它数据库

二、使用

使用gorm.Open()函数返回一个gorm.DB结构体后,我们可以使用gorm.DB结构体提供的方法操作数据库。其实gorm.DB是在Go语言的database/sql库中的sql.DB结构体上再封装,因为gorm.DB提供许多和sql.DB一样的方法。下面我们演示如何使用gorm.DB进行创建、查询、更新、删除等最基本的操作。

首先使用gorm.Open函数连接到数据库,并指定数据库的DSN(数据源名称)。然后使用db.AutoMigrate方法创建用户表。使用db.Create方法创建一个新的用户记录,并使用db.First方法查询单个用户记录。我们还使用db.Model和Update方法更新用户记录,以及db.Delete方法删除用户记录。

注意:dsn需要根据你的数据库配置进行修改,包括用户名、密码、主机和端口等信息。


go
package main

import (
    "fmt"

    "gorm.io/driver/mysql"
    "gorm.io/gorm"

)

type User struct {
    ID   uint   `gorm:"primaryKey"`
    Name string `gorm:"column:name"`
    Age  int    `gorm:"column:age"`
}

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

    // 自动迁移模式,创建表
    err = db.AutoMigrate(&User{})
    if err != nil {    //对错误信息的筛查
        panic("failed to migrate database")
    }
    
    // 创建用户Alice
    user := User{Name: "Alice", Age: 25}
    result := db.Create(&user)
    if result.Error != nil {
        panic("failed to create user")
    }
    
    // 查询单个用户
    var retrievedUser User
    result = db.First(&retrievedUser, user.ID)
    if result.Error != nil {
        panic("failed to retrieve user")
    }
    fmt.Println(retrievedUser)
    
    // 更新用户
    result = db.Model(&retrievedUser).Update("Age", 30)
    if result.Error != nil {
        panic("failed to update user")
    }
    
    // 删除用户
    result = db.Delete(&retrievedUser)
    if result.Error != nil {
        panic("failed to delete user")
    }

}


个人感想:去年只在在线平台试过数据库的操作,之后只在安装程序时跟着教程 使用数据库操作指令。这次课学到了很多,也让我知道了自己还有很多需要学习的地方。学习计算机不能只追求工具的使用,还要尽量了解背后的逻辑以及实现的原理,这对于提高创新能力有很大帮助——了解越多就知道更多可以优化的点。