全部產品
Search
文件中心

ApsaraDB for OceanBase (Deprecated):GORM 串連 OceanBase 資料庫樣本程式

更新時間:Jul 01, 2024

本文將介紹如何使用 GORM 和 OceanBase 資料庫構建一個應用程式,實現建立表、插入資料和查詢資料等基本操作。

image.png點擊下載 gorm-oceanbase 樣本工程

前提條件

安裝 OceanBase 資料庫、 Go 語言和相關驅動 ,並確保已經正確配置了環境變數。

說明

本文檔編寫代碼使用的工具是 IntelliJ IDEA 2021.3.2 (Community Edition) 版本,您也可以根據個人喜好選擇適合自己的工具查看範例程式碼。

  • 安裝 OceanBase 資料庫

  • 安裝 Go 語言

  • 安裝 Go-SQL-Driver/MySQL 驅動

操作步驟

說明

本文中給出的操作步驟是在 Windows 環境下產生的。如果您使用的是其他動作系統內容或編譯器,那麼操作步驟可能會略有不同。

  1. (可選)安裝 Go 語言和驅動。

  2. 擷取 OceanBase 資料庫連接資訊。

  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

步驟二:擷取 OceanBase 資料庫連接資訊

聯絡 OceanBase 資料庫部署人員或者管理員擷取相應的資料庫連接資訊。

obclient  -h{host} -u{user_name} -p****** -P{port} -D{schema_name}

資料庫連接串包含了訪問資料庫所需的參數資訊,可通過資料庫連接串驗證登入資料庫,保證串連串參數資訊正確。

說明

test.go檔案中需要這裡的 URL 資訊。

參數說明:

  • hostOceanBase 資料庫連接的網域名稱。

  • user_name:租戶的串連帳號。

  • password:提供賬戶密碼。

  • port:OceanBase 資料庫連接連接埠,MySQL 模式租戶預設是 3306。

  • schema_name:需要訪問的 Schema 名稱。

步驟三: 修改gorm-oceanbase專案中的資料庫連接資訊

根據步驟二:擷取 OceanBase 資料庫連接資訊中的資訊修改test.go檔案中的資料庫連接資訊。選中test.go檔案,按右鍵選擇開啟檔案,可通過記事本或其他編輯軟體開啟。

image.png

樣本如下:

  • OBServer 節點的 IP 位址為xxx.xxx.xxx.xxx

  • 訪問連接埠使用的是 3306。

  • 需要訪問的 Schema 名稱為test

  • 租戶的串連賬戶是root

  • 密碼是******

範例程式碼如下:

dsn := "root:******@tcp(xxx.xxx.xxx.xxx:3306)/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: "OceanBase", 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.SinceFunction Compute程式已耗用時間,調用logrus.WithFields函數建立帶有欄位的日誌記錄器,調用Debug函數輸出日誌資訊。

    代碼如下:

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

完整的代碼展示

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
)

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

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: "OceanBase", 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 的內容在 OceanBase 資料庫開源社區中也有更多資訊,詳情請參考 Go-SQL-Driver/MySQL