DBリゾルバは、GORMに複数データベースのサポートを追加します。以下の機能がサポートされています。
複数のソース、レプリカ
読み取り/書き込みの分割
作業中のテーブル/構造体に基づく自動接続切り替え
手動接続切り替え
ソース/レプリカの負荷分散
RAW SQLで動作します
トランザクション
https://github.com/go-gorm/dbresolver
使用方法 import ( "gorm.io/gorm" "gorm.io/plugin/dbresolver" "gorm.io/driver/mysql" ) db, err := gorm.Open(mysql.Open("db1_dsn" ), &gorm.Config{}) db.Use(dbresolver.Register(dbresolver.Config{ Sources: []gorm.Dialector{mysql.Open("db2_dsn" )}, Replicas: []gorm.Dialector{mysql.Open("db3_dsn" ), mysql.Open("db4_dsn" )}, Policy: dbresolver.RandomPolicy{}, TraceResolverMode: true , }).Register(dbresolver.Config{ Replicas: []gorm.Dialector{mysql.Open("db5_dsn" )}, }, &User{}, &Address{}).Register(dbresolver.Config{ Sources: []gorm.Dialector{mysql.Open("db6_dsn" ), mysql.Open("db7_dsn" )}, Replicas: []gorm.Dialector{mysql.Open("db8_dsn" )}, }, "orders" , &Product{}, "secondary" ))
自動接続切り替え DBリゾルバは、作業中のテーブル/構造体に基づいて接続を自動的に切り替えます。
RAW SQLの場合、DBリゾルバはSQLからテーブル名を抽出してリゾルバと照合し、SQLが`SELECT`(`SELECT... FOR UPDATE`を除く)で始まる場合を除き、`sources`を使用します。例えば、
db.Table("users" ).Rows() db.Model(&User{}).Find(&AdvancedUser{}) db.Exec("update users set name = ?" , "jinzhu" ) db.Raw("select name from users" ).Row().Scan(&name) db.Create(&user) db.Delete(&User{}, "name = ?" , "jinzhu" ) db.Table("users" ).Update("name" , "jinzhu" ) db.Find(&Pet{}) db.Save(&Pet{}) db.Find(&Order{}) db.Table("orders" ).Find(&Report{})
読み取り/書き込み分割 現在使用されているGORMコールバック に基づいて、DBリゾルバで読み取り/書き込みを分割します。
`Query`、`Row`コールバックの場合、`Write`モードが指定されていない限り、`replicas`を使用します。 `Raw`コールバックの場合、ステートメントは読み取り専用と見なされ、SQLが`SELECT`で始まる場合は`replicas`を使用します。
手動接続切り替え db.Clauses(dbresolver.Write).First(&user) db.Clauses(dbresolver.Use("secondary" )).First(&user) db.Clauses(dbresolver.Use("secondary" ), dbresolver.Write).First(&user)
トランザクション トランザクションを使用する場合、DBリゾルバはトランザクションを使い続け、設定に基づいてソース/レプリカに切り替えません。
ただし、トランザクションを開始する前に使用するDBを指定できます。例えば、
tx := db.Clauses(dbresolver.Read).Begin() tx := db.Clauses(dbresolver.Write).Begin() tx := db.Clauses(dbresolver.Use("secondary" ), dbresolver.Write).Begin()
負荷分散 GORMは、ポリシーに基づいてソース/レプリカの負荷分散をサポートしています。ポリシーは、以下のインターフェースを実装する構造体である必要があります。
type Policy interface { Resolve([]gorm.ConnPool) gorm.ConnPool }
現在、`RandomPolicy`のみが実装されており、他のポリシーが指定されていない場合はデフォルトのオプションです。
コネクションプール db.Use( dbresolver.Register(dbresolver.Config{ }). SetConnMaxIdleTime(time.Hour). SetConnMaxLifetime(24 * time.Hour). SetMaxIdleConns(100 ). SetMaxOpenConns(200 ) )