本ドキュメントでは、GORM と OceanBase Cloud データベースを使用してアプリケーションを構築し、テーブルの作成、データの挿入、データのクエリなどの基本操作を実装する方法について説明します。
前提条件
OceanBase Cloud データベースインスタンスを作成し、Go 言語と関連ドライバをインストールして、環境変数が正しく設定されていることを確認します。
説明
本ドキュメントのコード作成に使用したツールは IntelliJ IDEA 2021.3.2 (Community Edition) です。お好みに応じて適切なツールを選択し、サンプルコードを確認することもできます。
- OceanBase Cloud データベースアカウントを登録し、クラスタインスタンスと MySQL互換モード のテナントを作成していること。詳細は、クラスタインスタンスの作成 および テナントの作成 をご参照ください。
- Go 言語のインストール
- Go-SQL-Driver/MySQL ドライバのインストール
操作手順
説明
本ドキュメントに記載されている手順は、Windows 環境で作成されたものです。他のオペレーティングシステム環境やコンパイラを使用している場合、手順が若干異なる場合があります。
- (オプション)Go 言語とドライバをインストールします。
- OceanBase Cloud データベースの接続情報を取得します。
gorm-oceanbaseプロジェクト内のデータベース接続情報を変更します。gorm-oceanbaseプロジェクトを実行します。
操作手順 1: (オプション)Go 言語とドライバのインストール
すでに Go 言語と Go-SQL-Driver/MySQL ドライバをインストールしている場合は、この手順をスキップできます。インストールしていない場合は、以下の手順に従ってインストールしてください。
Go 言語のインストール
Go 言語インストールパッケージのダウンロード: Go公式サイト から、ご使用のオペレーティングシステムに適したインストールパッケージをダウンロードできます。
説明
本ドキュメントで使用する Go インストールパッケージ名は go1.20.6.windows-amd64.msi です。
Go 言語のインストール: ダウンロードしたインストールパッケージをダブルクリックし、プロンプトに従ってインストールします。
環境変数の設定: 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 言語のインストール時にインストールディレクトリを変更した場合は、対応するディレクトリに置き換えてください。インストールの検証: Shell コマンドラインで以下のコマンドを入力し、Go 言語のバージョン情報を確認して、インストールが成功したか検証します。
C:\Users\admin\> go version go version go1.20.6 windows/amd64
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をインストールできます。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 インストールディレクトリに置き換えて操作する必要があります。go installを使用してインストールします。go install mysql注意
一部のバージョンでは、
go installのデフォルト実行ディレクトリが/srcではない場合があります。go install実行後のエラーメッセージから実際のディレクトリを判断できます。例えば、cannot find package "mysql" in: /usr/local/go/src/vendor/mysqlというエラーが出た場合、mysql フォルダを/src/vendorディレクトリに配置してからインストールコマンドを実行する必要があります。Go-SQL-Driver/MySQL ドライバがインストールされているか確認します。インストールに失敗した場合は、エラーメッセージに従って修正してください。
go list -m github.com/go-sql-driver/mysql
操作手順 2: OceanBase Cloud データベースの接続情報の取得
OceanBase Cloudコンソール にログインします。インスタンス一覧ページで対象インスタンスの情報を展開し、対象テナントの下で 接続 > 接続文字列を取得 を選択します。
詳細な操作については、接続文字列の取得 をご参照ください。
作成済みの OceanBase Cloud データベースに基づいて、以下の URL の対応する情報を入力します。
obclient -h{host} -u{username} -p****** -P{port} -D{schema_name}データベース接続文字列には、データベースへのアクセスに必要なパラメータ情報が含まれています。データベース接続文字列を使用してデータベースへのログインを検証し、接続文字列のパラメータ情報が正しいことを確認できます。
説明
test.goファイルでは、ここの URL 情報が必要です。パラメータの説明:
host:OceanBase Cloud データベースの接続アドレスを指定します。例:t********.********.oceanbase.cloud。user_name:データベースにアクセスするためのアカウントを指定します。password:アカウントのパスワードを指定します。port:OceanBase Cloud データベースの接続ポートを指定します。デフォルトは 3306 です。schema_name:アクセスする Schema 名を指定します。
操作手順 3: gorm-oceanbase プロジェクト内のデータベース接続情報の変更
手順 2: OceanBase Cloud データベースの接続情報の取得 の情報に基づいて、test.go ファイル内のデータベース接続情報を変更します。test.go ファイルを選択し、右クリックして プログラムから開く を選択し、メモ帳 またはその他の編集ソフトウェアで開くことができます。
例:
- データベースのアクセスアドレスは
t********.********.oceanbase.cloudです。 - アクセスポートは 3306 を使用します。
- アクセスする Schema 名は
testです。 - テナントの接続アカウントは
mysql001です。 - パスワードは
******です。
サンプルコードは以下の通りです:
dsn := "mysql001:******@tcp(t********.********.oceanbase.cloud:3306)/test?charset=utf8mb4&parseTime=True&loc=Local"
操作手順 4: go-oceanbase プロジェクトの実行
コードの編集が完了したら、プロジェクトディレクトリでコマンドラインターミナルを開き、go run を使用して Go ファイルを直接実行します。以下のコマンドを実行します。
PS D:\demo\go-demo\gorm-oceanbase> go run test.go
(オプション)Linux または macOS 環境では、一時的な環境変数を設定してから go run を実行する必要があります。
```shell
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 ファイルは、プロジェクトの依存関係情報を定義するために使用されます。各依存関係は、ライブラリ名、バージョン番号、ハッシュ値の 3 つの部分で構成されます。
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 ファイルには以下の内容が含まれます。
mainパッケージの定義。package mainは、これが実行可能プログラムのパッケージであることを示します。このパッケージにはmain()関数が含まれており、この関数はプログラムの実行時に実行されます。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:ログ出力とフォーマットの機能を提供するために使用されます。
コードは以下の通りです:
```go
import (
fmt time os gorm.io/driver/mysql gorm.io/gorm golang.org/x/text/transform github.com/sirupsen/logrus ) ```
User構造体の定義。ユーザーの基本情報を表すために
Userという名前の構造体を定義します。これには、ユーザーの一意の識別子ID、ユーザーの名前Name、ユーザーの年齢Age、ユーザーの誕生日Birthdayの 4 つのフィールドが含まれます。
コードは以下の通りです:
```go
type User struct {
ID int
Name string
Age int
Birthday time.Time
}
```
transformString関数の定義。 文字列を指定されたエンコーディング形式に変換するために、transformStringという名前の関数を定義します。この関数はstrとencoderの 2 つのパラメータを受け取ります。関数はtransform.String関数を呼び出して文字列を指定されたエンコーディング形式に変換し、変換中にエラーが発生した場合は元の文字列を返します。最後に、関数は変換後の文字列または元の文字列を返します。
コードは以下の通りです:
```go
func transformString(str string, encoder transform.Transformer) string {
result, _, err := transform.String(encoder, str)
if err != nil {
return str
}
return result
}
```
main関数の定義。main関数を呼び出すことで、作成されたユーザー情報に対して追加、削除、変更、クエリの操作を行い、logrusを使用して対応するデバッグログをコンソールに出力します。logrusの初期化。logrusパッケージを使用してログ出力を初期化し、ログ出力形式をテキスト形式に、ログレベルをDebugレベルに設定して、標準出力ストリームに出力します。
コードは以下の通りです:
```go
logrus.SetFormatter(&logrus.TextFormatter{})
logrus.SetLevel(logrus.DebugLevel)
logrus.SetOutput(os.Stdout)
```
データベースの接続。
dsnという名前の文字列変数を定義します。これには、ユーザー名、パスワード、ホストアドレス、ポート番号、データベース名、文字セットなど、MySQL データベースへの接続に必要な情報が含まれます。gorm.Open関数を呼び出して MySQL データベースに接続し、dsn変数とgorm.Config型のパラメータを渡して、接続オブジェクトを返します。接続エラーが発生した場合は、エラー情報を出力してプログラムを終了します。
コードは以下の通りです:
```go
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
}
```
データベース操作。
gorm.DBオブジェクトを使用して、自動マイグレーション、データの挿入、データのクエリ、データの更新、データの削除などのデータベース操作を行います。具体的なプロセスは以下の通りです。db.AutoMigrate関数を呼び出して、User構造体に対応するテーブルを自動的にマイグレーションします。テーブルが存在しない場合は作成します。deferキーワードとdb.Migrator().DropTable関数を使用して、usersテーブルの削除を遅延させます。つまり、プログラムの終了時にテーブルを削除します。userという名前のUser構造体インスタンスを作成し、データベースに挿入します。- ID が 1 のユーザーをクエリし、クエリ結果を出力します。
- ID が 1 のユーザーの情報を更新し、データベースに保存します。
- ID が 1 のユーザーを削除し、削除結果を出力します。
コードは以下の通りです:
```go
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)
```
ログの出力。
time.Since関数を呼び出してプログラムの実行時間を計算し、logrus.WithFields関数を呼び出してフィールド付きのロガーを作成し、Debug関数を呼び出してログ情報を出力します。
コードは以下の通りです:
```go
logrus.WithFields(logrus.Fields{
duration: time.Since(start),
}).Debug("DropTable")
```
完全なコードの表示
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
)
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=
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 をご参照ください。