跳到主要内容

GORM 连接 seekdb 示例程序

本文将介绍如何使用 GORM 和 seekdb 构建一个应用程序,实现创建表、插入数据和查询数据等基本操作。

点击下载 gorm-oceanbase 示例工程

前提条件

安装 seekdb、 Go 语言和相关驱动,并确保已经正确配置了环境变量。

信息

本文档编写代码使用的工具是 IntelliJ IDEA 2021.3.2 (Community Edition) 版本,您也可以根据个人喜好选择适合自己的工具查看示例代码。

  • 安装 seekdb
  • 安装 Go 语言
  • 安装 Go-SQL-Driver/MySQL 驱动

操作步骤

信息

本文中给出的操作步骤是在 Windows 环境下生成的。如果您使用的是其他操作系统环境或编译器,那么操作步骤可能会略有不同。

  1. (可选)安装 Go 语言和驱动。
  2. 获取 seekdb 连接信息。
  3. 修改 gorm-oceanbase 项目中的数据库连接信息。
  4. 运行 gorm-oceanbase 项目。

步骤一:(可选)安装 Go 语言和驱动

若您已经安装了 Go 语言和 Go-SQL-Driver/MySQL 驱动,可以直接跳过此步骤。若您未安装,可根据以下步骤进行安装。

  1. 安装 Go 语言

    1. 下载 Go 语言安装包:可以从 Go 官网 下载适合自己操作系统的安装包。

      信息

      本文档使用的 Go 安装包名为 go1.20.6.windows-amd64.msi。

    2. 安装 Go 语言:双击下载的安装包,按照提示进行安装。

    3. 配置环境变量:将 Go 语言的安装路径添加到系统的 PATH 环境变量中。

      • 在 Windows 环境中,可以在 控制面板 > 系统和安全 > 系统 > 高级系统设置 > 环境变量 > 系统变量 中增加 Path 的值为 C:\usr\local\go\bin

      • 在 Linux 或 macOS 环境中,可以编辑 ~/.bashrc~/.bash_profile 文件,在其中添加以下内容:

        export PATH=$PATH:/usr/local/go/bin
      信息

      \usr\local\go\bin为默认安装目录,若在安装 Go 语言时修改了安装目录,请替换为对应的目录。

    4. 验证安装:在 Shell 命令行中输入以下命令,查看 Go 语言的版本信息,以验证安装是否成功:

      C:\Users\admin\> go version
      go version go1.20.6 windows/amd64
  2. 安装 Go-SQL-Driver/MySQL 驱动

    根据 Go 语言的不同版本,可以选择不同的安装方式,安装 Go-SQL-Driver/MySQL 驱动时需要进入到对应的项目目录下打开命令行终端。关于 Go-SQL-Driver/MySQL 的详细信息,您可参考 Github

    安装命令如下:

    C:\Users\admin\Desktop\go-oceanbase>go get -u github.com/go-sql-driver/mysql
    go: downloading github.com/go-sql-driver/mysql v1.7.1
    go: added github.com/go-sql-driver/mysql v1.7.1

    如果由于版本或网络的原因,无法通过 go get 命令安装时,可通过 go install 命令进行 go-sql-driver/mysql 安装。

    1. go/src 目录克隆 github 中的 go-sql-driver/mysql 仓库。

      cd /usr/local/go/src   
      git clone https://github.com/go-sql-driver/mysql.git
      提示

      /usr/local/go/src 需要替换成 Go 实际安装目录操作。

    2. 通过 go install 进行安装。

      go install mysql
      提示

      部分版本 go install 的默认执行目录可能不是 /src,可以通过 go install 执行后的报错判断实际目录。例如,报错 cannot find package "mysql" in: /usr/local/go/src/vendor/mysql,则应该将 mysql 文件夹放在 /src/vendor 目录下再执行安装命令。

    3. 检查 Go-SQL-Driver/MySQL 驱动是否已经安装,若安装失败,请按照报错信息进行修改。

      go list -m github.com/go-sql-driver/mysql

步骤二:获取 seekdb 连接信息

联系 seekdb 部署人员或者管理员获取相应的数据库连接信息。

mysql  -h{host} -u{username} -p****** -P{port} -D{schema_name}

数据库连接串包含了访问数据库所需的参数信息,可通过数据库连接串验证登录数据库,保证连接串参数信息正确。

信息

test.go 文件中需要这里的 URL 信息。

参数说明:

  • host:提供 seekdb 的连接 IP。应该被实际的 IP 替换,也可以使用本地 IP 及 127.0.0.1。
  • user_name:提供连接账户。格式:用户名
  • password:提供账户密码。
  • port:提供 seekdb 接端口。应该被实际的端口替换,默认是 2881,在部署 seekdb 时可自定义。
  • schema_name:需要访问的 Schema 名称。

步骤三: 修改 gorm-oceanbase 项目中的数据库连接信息

根据 步骤二:获取 seekdb 连接信息 中的信息修改 test.go 文件中的数据库连接信息。选中 test.go 文件,右键单击选择打开方式,可通过记事本或其他编辑软件打开。

test.go

示例如下:

  • seekdb 的 IP 地址为 10.10.10.1
  • 访问端口使用的是 2881。
  • 需要访问的 Schema 名称为 test
  • 连接账户是 root
  • 密码是 ******

示例代码如下:

dsn := "root:******@tcp(10.10.10.1:2881)/test?charset=utf8mb4&parseTime=True&loc=Local"

步骤四:运行 go-oceanbase 项目

代码编辑完成后,在项目目录下打开命令行终端,通过 go run 直接运行 Go 文件运行如下命令运行:

PS D:\demo\go-demo\gorm-oceanbase> go run test.go

(可选)在 Linux 或 macOS 环境中需要配置临时环境变量后,才能运行 go run

export PATH=$PATH:/usr/local/go/bin
go run test.go

运行后返回如下内容,说明数据库连接成功,示例语句正确执行:

PS D:\demo\go-demo\gorm-oceanbase> go run test.go
1
<nil>
1
{1 OceanBase 12 2022-06-01 08:00:00 +0800 CST}
<nil>
1
{1 ob 13 2023-06-01 00:00:00 +0000 UTC}
<nil>
1
1
<nil>
1
time="2023-08-09T15:55:46+08:00" level=debug msg=DropTable duration=589.2031ms

2023/08/09 15:55:47 D:/demo/go-demo/gorm-oceanbase/test.go:85 SLOW SQL >= 200ms
[336.194ms] [rows:0] DROP TABLE IF EXISTS `users` CASCADE

项目代码介绍

点击 gorm-oceanbase 下载项目代码,是一个名称为 gorm-oceanbase 的压缩包。 解压后,得到一个名为 gorm-oceanbase 的文件夹。目录结构如下所示:

|-- go.mod
|-- go.sum
|-- test.go

文件说明:

  • go.mod:Go 语言模块文件,用于定义项目的模块依赖关系和版本信息。
  • go.sum:Go V1.11 及以上版本中新增的模块管理文件,用于记录项目依赖的模块及其版本信息,以及对应的校验和(Checksum)。
  • test.go: Go 源代码文件,其中包含项目的示例代码。

go.mod 代码介绍

go.mod 文件用于定义项目的模块名称、Go 版本号以及依赖项相关声明。

go.mod 文件包含以下内容:

  • module gorm-oceanbase:这是项目的模块名称,它定义了项目的命名空间。在 Go 1.16 及更高版本中,模块名称必须与项目的根目录名称匹配。

  • go 1.20:这是项目所需的 Go 版本。

  • require:这是项目的依赖项声明。它指定了列出了项目所依赖的第三方库及其版本信息。该依赖项是间接依赖项,与另一个依赖项 go.sum 相关联。

    • github.com/go-sql-driver/mysql:Go-SQL-Driver/MySQL 驱动,用于连接和操作 MySQL 数据库。
    • github.com/jinzhu/inflection:字符串转换库,用于将字符串转换为单数形式、复数形式、驼峰形式等。
    • github.com/jinzhu/now:时间处理库,用于获取当前时间、计算时间差、格式化时间等。
    • github.com/sirupsen/logrus:日志库,用于记录程序运行时的日志信息。
    • golang.org/x/sys:系统库,提供了一些系统级别的操作函数和常量。
    • golang.org/x/text:文本处理库,用于处理 Unicode 字符串、格式化数字等。
    • gorm.io/driver/mysql:GORM 的 MySQL 驱动,用于在 GORM 中连接和操作 MySQL 数据库。
    • gorm.io/gorm:GORM ORM 框架,用于简化数据库操作。

代码如下:

module gorm-oceanbase

go 1.20

require (
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.12.0 // indirect
gorm.io/driver/mysql v1.5.1 // indirect
gorm.io/gorm v1.25.2 // indirect
)

go.sum 代码介绍

go.sum 文件用于定义项目的依赖项信息,每个依赖项都由三部分组成,分别是库的名称、版本号和哈希值。

go.sum 文件包含以下内容:

  • github.com/sirupsen/logrus:日志库,用于记录程序运行时的日志信息。
  • golang.org/x/text:文本处理库,用于处理 Unicode 字符串、格式化数字等。
  • gorm.io/driver/mysql:GORM 的 MySQL 驱动,用于在 GORM 中连接和操作 MySQL 数据库。
  • gorm.io/gorm:GORM ORM 框架,用于简化数据库操作。
信息

go.sum 文件根据运行环境的不同所需要的依赖不同,请根据执行提示下载您所需的依赖项。

代码如下:

github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=

test.go 代码介绍

test.go 文件定义了如何使用 Go-SQL-Driver/MySQL 驱动来连接 MySQL 数据库,并使用 GORM 提供的 API 进行数据库操作。 test.go 文件包含以下内容:

  1. 定义 main 包。 package main 表示这是一个可执行程序的包,这个包包含了一个 main() 函数,这个函数会在程序运行时被执行。

  2. 定义 import 包。

    import 语句导入了以下几个包:

    • fmt:用于提供格式化输入和输出的函数。它定义了一组函数,用于将数据格式化为字符串并输出到控制台或其他设备。
    • time:用于提供了一些时间相关的函数和类型。
    • os:用于提供了一些操作系统相关的函数和类型。
    • gorm.io/driver/mysql:MySQL 数据库驱动,用于连接和操作 MySQL 数据库。
    • gorm.io/gorm:用于将 Go 语言的结构体映射到数据库表中,并提供了一些查询和操作数据库的方法。
    • golang.org/x/text/transform:用于提供了一些文本处理的基础功能,如字符集转换、Unicode 处理等。
    • github.com/sirupsen/logrus:用于提供了一些日志输出和格式化的功能。

    代码如下:

    import (
    "fmt"
    "time"
    "os"
    "gorm.io/driver/mysql"
    "gorm.io/gorm"
    "golang.org/x/text/transform"
    "github.com/sirupsen/logrus"
    )
  3. 定义 User 结构体。

    定义了一个名为 User 的结构体,用于表示一个用户的基本信息,它包含了四个字段:用户的唯一标识符 ID,用户的姓名 Name,用户的年龄 Age,用户的生日 Birthday

    代码如下:

    type User struct {
    ID int
    Name string
    Age int
    Birthday time.Time

    }
  4. 定义 transformString 函数。 定义一个名为 transformString 的函数,用于将一个字符串转换为指定的编码格式。它接受两个参数:strencoder,函数通过调用 transform.String 函数将字符串转换为指定的编码格式,如果转换过程中出现错误,则返回原始字符串。最后,函数返回转换后的字符串或原始字符串。

    代码如下:

    func transformString(str string, encoder transform.Transformer) string {
    result, _, err := transform.String(encoder, str)
    if err != nil {
    return str
    }
    return result
    }
  5. 定义 main 函数。

    通过调用 main 函数,对创建的用户信息进行了增删改查的操作,并使用了 logrus 输出相应的调试日志到控制台。

    1. 初始化 logrus

      使用 logrus 包对日志输出进行初始化,设置日志输出格式为文本格式,日志级别为 Debug 级别,并输出到标准输出流中。

      代码如下:

      logrus.SetFormatter(&logrus.TextFormatter{})
      logrus.SetLevel(logrus.DebugLevel)
      logrus.SetOutput(os.Stdout)
    2. 连接数据库。

      定义名为 dsn 的字符串变量,它包含了连接 MySQL 数据库所需的信息,包括用户名、密码、主机地址、端口号、数据库名称、字符集等。调用 gorm.Open 函数连接 MySQL 数据库,传入 dsn 变量和一个 gorm.Config 类型的参数,并返回一个连接对象。如果连接出现错误,则输出错误信息并退出程序。

      代码如下:

      dsn := "user_name:******@tcp(host:port)/schema_name?charset=utf8mb4&parseTime=True&loc=Local"
      db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
      if err != nil {
      fmt.Println(err.Error())
      return
      }
    3. 数据库操作。

      使用 gorm.DB 对象进行数据库操作,包括自动迁移、插入数据、查询数据、更新数据和删除数据等操作。具体过程如下:

      1. 调用 db.AutoMigrate 函数,自动迁移 User 结构体对应的表,如果表不存在则创建表。使用 defer 关键字和 db.Migrator().DropTable 函数,延迟删除 users 表,即在程序结束时删除表。
      2. 创建一个名为 userUser 结构体实例,并将其插入到数据库中。
      3. 查询 ID 为 1 的用户,并输出查询结果。
      4. 更新 ID 为 1 的用户的信息,并将其保存到数据库中。
      5. 删除 ID 为 1 的用户,并输出删除结果。

      代码如下:

      db.AutoMigrate(&User{})
      defer db.Migrator().DropTable("users")
      // 记录开始时间
      start := time.Now()
      // 创建一个名为 user 的 User 结构体实例,并将其插入到数据库中。
      user := User{Name: "seekdb", Age: 12, Birthday: time.Date(2022, 06, 01, 00, 00, 00, 00, time.UTC)}
      result := db.Create(&user)
      fmt.Println(user.ID)
      fmt.Println(result.Error)
      fmt.Println(result.RowsAffected)
      // 查询 ID 为 1 的用户,并输出查询结果。
      user = User{ID: 1}
      result = db.First(&user)
      fmt.Println(user)
      fmt.Println(result.Error)
      fmt.Println(result.RowsAffected)
      // 更新 ID 为 1 的用户的信息,并将其保存到数据库中。
      user = User{ID: 1, Name: "ob", Age: 13, Birthday: time.Date(2023, 06, 01, 00, 00, 00, 00, time.UTC)}
      result = db.Save(&user)
      fmt.Println(user)
      fmt.Println(result.Error)
      fmt.Println(result.RowsAffected)
      // 删除 ID 为 1 的用户,并输出删除结果。
      user = User{ID: 1}
      result = db.Delete(&user)
      fmt.Println(user.ID)
      fmt.Println(result.Error)
      fmt.Println(result.RowsAffected)
  6. 输出日志。

    调用 time.Since 函数计算程序运行时间,调用 logrus.WithFields 函数创建带有字段的日志记录器,调用 Debug 函数输出日志信息。

    代码如下:

    logrus.WithFields(logrus.Fields{
    "duration": time.Since(start),
    }).Debug("DropTable")

完整的代码展示

tab go.mod

module gorm-oceanbase

go 1.20

require (
github.com/go-sql-driver/mysql v1.7.1 // indirect
github.com/jinzhu/inflection v1.0.0 // indirect
github.com/jinzhu/now v1.1.5 // indirect
github.com/sirupsen/logrus v1.9.3 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.12.0 // indirect
gorm.io/driver/mysql v1.5.1 // indirect
gorm.io/gorm v1.25.2 // indirect
)

tab go.sum

github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
gorm.io/driver/mysql v1.5.1 h1:WUEH5VF9obL/lTtzjmML/5e6VfFR/788coz2uaVCAZw=
gorm.io/driver/mysql v1.5.1/go.mod h1:Jo3Xu7mMhCyj8dlrb3WoCaRd1FhsVh+yMXb1jUInf5o=
gorm.io/gorm v1.25.2 h1:gs1o6Vsa+oVKG/a9ElL3XgyGfghFfkKA2SInQaCyMho=
gorm.io/gorm v1.25.2/go.mod h1:L4uxeKpfBml98NYqVqwAdmV1a2nBtAec/cf3fpucW/k=

tab test.go

package main

import (
"fmt"
"time"
"os"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"golang.org/x/text/transform"
"github.com/sirupsen/logrus"
)

type User struct {
ID int
Name string
Age int
Birthday time.Time

}

// 将字符串转换为指定的编码格式
func transformString(str string, encoder transform.Transformer) string {
result, _, err := transform.String(encoder, str)
if err != nil {
return str
}
return result
}

func main() {

// 初始化 logrus
logrus.SetFormatter(&logrus.TextFormatter{})
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(os.Stdout)


dsn := "user_name:******@tcp(host:port)/schema_name?charset=utf8mb4&parseTime=True&loc=Local"

db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
fmt.Println(err.Error())
return

}

db.AutoMigrate(&User{})
defer db.Migrator().DropTable("users")

// 记录开始时间
start := time.Now()

user := User{Name: "seekdb", Age: 12, Birthday: time.Date(2022, 06, 01, 00, 00, 00, 00, time.UTC)}
result := db.Create(&user)
fmt.Println(user.ID)
fmt.Println(result.Error)
fmt.Println(result.RowsAffected)

user = User{ID: 1}
result = db.First(&user)
fmt.Println(user)
fmt.Println(result.Error)
fmt.Println(result.RowsAffected)

user = User{ID: 1, Name: "ob", Age: 13, Birthday: time.Date(2023, 06, 01, 00, 00, 00, 00, time.UTC)}
result = db.Save(&user)
fmt.Println(user)
fmt.Println(result.Error)
fmt.Println(result.RowsAffected)

user = User{ID: 1}
result = db.Delete(&user)
fmt.Println(user.ID)
fmt.Println(result.Error)
fmt.Println(result.RowsAffected)



// 输出日志
logrus.WithFields(logrus.Fields{
"duration": time.Since(start),
}).Debug("DropTable")

}

相关文档

有关 Go-SQL-Driver/MySQL 的更多信息,参见 Go-SQL-Driver/MySQL