本記事では、GORM と OceanBase データベースを使用してアプリケーションを構築し、テーブルの作成、データの挿入、クエリなどの基本的な操作を実現する方法について説明します。
前提条件
OceanBaseデータベース、Go言語、および関連ドライバをインストールし、環境変数が正しく設定されていることを確認してください。
説明
このドキュメントでコードを記述する際に使用したツールはIntelliJ IDEA 2021.3.2 (Community Edition)です。個人の好みに応じて、適切なツールを選択してサンプルコードを参照することもできます。
- OceanBaseデータベースのインストール
- Go言語のインストール
- Go-SQL-Driver/MySQLドライバのインストール
手順
説明
本記事で示す操作手順は、Windows環境で生成されたものです。他のOS環境やコンパイラを使用している場合は、手順が若干異なる可能性があります。
- (オプション)Go言語とドライバーをインストールします。
- OceanBaseデータベースの接続情報を取得します。
gorm-oceanbaseプロジェクトのデータベース接続情報を修正します。gorm-oceanbaseプロジェクトを実行します。
ステップ1:(オプション) Go言語とドライバのインストール
Go言語とGo-SQL-Driver/MySQLドライバが既にインストール済みの場合は、この手順をスキップできます。インストールしていない場合は、以下の手順に従ってインストールしてください。
Go言語のインストール
Go言語のインストーラーをダウンロードします。Go公式サイトから、ご使用のOSに適したインストーラーをダウンロードします。
説明
本記事で使用している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データベースの接続情報を取得する
OceanBaseデータベースのデプロイ担当者または管理者から、該当するデータベース接続情報を取得します。
obclient -h{host} -u{user_name} -p****** -P{port} -D{schema_name}
データベース接続文字列には、データベースへのアクセスに必要なパラメータ情報が含まれています。データベース接続文字列を使用してデータベースへのログインを検証し、接続文字列のパラメータ情報が正しいことを確認できます。
説明
test.go ファイルには、このURL情報が必要です。
パラメータの説明:
host:OceanBaseデータベースの接続IPアドレスを指定します。ODP接続方式ではODPアドレスを使用し、直接接続方式ではOBServerノードのIPアドレスを使用します。user_name:テナントの接続アカウントを指定します。ODP接続の一般的な形式はユーザー名@テナント名#クラスタ名またはクラスタ名:テナント名:ユーザー名です。直接接続方式の形式はユーザー名@テナント名です。password:アカウントのパスワードを指定します。port:OceanBaseデータベースの接続ポートを指定します。ODP接続方式のデフォルトポートは2883で、ODPデプロイ時にカスタマイズ可能です。直接接続方式のデフォルトポートは2881で、OceanBaseデータベースのデプロイ時にカスタマイズ可能です。schema_name:アクセスするSchema名を指定します。
ステップ3:gorm-oceanbase プロジェクトのデータベース接続情報を修正する
ステップ2:OceanBaseデータベースの接続情報を取得する の情報に基づいて、test.go ファイル内のデータベース接続情報を修正します。test.go ファイルを選択し、右クリックして 開く方法 を選択すると、メモ帳 または他のエディタで開くことができます。
例:
- OBServerノードのIPアドレスは
10.10.10.1です。 - アクセスポートは2881を使用します。
- アクセスするSchema名は
testです。 - テナントの接続アカウントは
root@mysqlです。root@mysqlはOceanBaseデータベースで作成されたMySQLモードのユーザーテナントであり、testはテナントroot@mysqlのユーザー名です。 - パスワードは
******です。
サンプルコードは以下のとおりです:
dsn := "root@mysql:******@tcp(10.10.10.1:2881)/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 を実行できません。
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:ログ出力とフォーマットの機能を提供します。
コード:
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つのフィールドが含まれます。コード:
type User struct { ID int Name string Age int Birthday time.Time }transformString関数を定義します。transformStringという名前の関数を定義し、文字列を指定されたエンコーディング形式に変換するために使用します。この関数はstrとencoderの2つのパラメータを受け取ります。関数はtransform.String関数を呼び出して文字列を指定されたエンコーディング形式に変換します。変換中にエラーが発生した場合は、元の文字列を返します。最終的に、関数は変換後の文字列または元の文字列を返します。コード:
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レベルに設定し、標準出力ストリームに出力します。コード:
logrus.SetFormatter(&logrus.TextFormatter{}) logrus.SetLevel(logrus.DebugLevel) logrus.SetOutput(os.Stdout)データベースに接続します。
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 }データベース操作を行います。
gorm.DBオブジェクトを使用してデータベース操作を行います。これには、自動マイグレーション、データの挿入、データのクエリ、データの更新、データの削除などの操作が含まれます。具体的な手順は以下のとおりです:db.AutoMigrate関数を呼び出して、User構造体に対応するテーブルを自動的にマイグレーションします。テーブルが存在しない場合は作成します。deferキーワードとdb.Migrator().DropTable関数を使用して、usersテーブルの削除を遅延させます。つまり、プログラム終了時にテーブルを削除します。userという名前のUser構造体のインスタンスを作成し、データベースに挿入します。- IDが1のユーザーをクエリし、クエリ結果を出力します。
- IDが1のユーザーの情報を更新し、データベースに保存します。
- 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)
ログを出力します。
time.Since関数を呼び出してプログラムの実行時間を計算し、logrus.WithFields関数を呼び出してフィールド付きのロガーを作成し、Debug関数を呼び出してログ情報を出力します。コード:
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を参照してください。
gorm-oceanbase サンプルプロジェクトをダウンロード