Afin de prendre en charge la réplication, nous avons décidé de diviser le point de terminaison de la base de données par lecture / écriture. J'ai examiné comment le gérer avec Go / Gorm2.
Chaque méthode Gorm est encapsulée dans un type qui a plusieurs connexions pour chaque point de terminaison. En faisant cela, le côté utilisant la connexion peut faire fonctionner le DB sans être conscient du point final.
db/connect.go
package db
import (
"os"
"gorm.io/driver/mysql"
"gorm.io/gorm"
)
type SqlHandler struct {
ReadConn *gorm.DB
WriteConn *gorm.DB
}
func Connect() *SqlHandler {
readConn, err := gorm.Open(GetDBConfig("read"))
if err != nil {
panic(err.Error())
}
writeConn, err := gorm.Open(GetDBConfig("write"))
if err != nil {
panic(err.Error())
}
sqlHandler := SqlHandler{
ReadConn: readConn,
WriteConn: writeConn,
}
return &sqlHandler
}
func GetDBConfig(endpoint string) (gorm.Dialector, *gorm.Config) {
USER := "myUser"
PASS := "hoge1234"
PROTOCOL := "tcp(" + endpoint + ":5050)"
DBNAME := "myDB"
OPTION := "charset=utf8&parseTime=True&loc=Local"
mysqlConfig := mysql.Config{
DSN: USER + ":" + PASS + "@" + PROTOCOL + "/" + DBNAME + "?" + OPTION,
}
config := &gorm.Config{}
return mysql.New(mysqlConfig), config
}
func (handler *SqlHandler) Find(out interface{}, where ...interface{}) *gorm.DB {
return handler.ReadConn.Find(out, where...)
}
func (handler *SqlHandler) Exec(sql string, values ...interface{}) *gorm.DB {
return handler.WriteConn.Exec(sql, values...)
}
func (handler *SqlHandler) First(out interface{}, where ...interface{}) *gorm.DB {
return handler.ReadConn.Find(out, where...)
}
func (handler *SqlHandler) Raw(sql string, values ...interface{}) *gorm.DB {
return handler.WriteConn.Raw(sql, values...)
}
func (handler *SqlHandler) Create(value interface{}) *gorm.DB {
return handler.WriteConn.Create(value)
}
func (handler *SqlHandler) Save(value interface{}) *gorm.DB {
return handler.WriteConn.Save(value)
}
func (handler *SqlHandler) Delete(value interface{}) *gorm.DB {
return handler.WriteConn.Delete(value)
}
func (handler *SqlHandler) Where(query interface{}, args ...interface{}) *gorm.DB {
return handler.WriteConn.Where(query, args...)
}
[Réplication](https://ja.wikipedia.org/wiki/%E3%83%AC%E3%83%97%E3%83%AA%E3%82%B1%E3%83%BC%E3%82 % B7% E3% 83% A7% E3% 83% B3)
Pour les parties qui peuvent être émises par la requête elle-même, telles que «func Exec» et «func Raw», il existe une possibilité de lecture / écriture, et il est difficile de décider lequel utiliser. Cette fois, je l'ai chargé d'écrire. Autant que possible, les utilisateurs veulent pouvoir l'utiliser sans connaître les endpoints ...
J'ai décidé d'utiliser CQRS, et je pense que l'écriture SQL solide est susceptible d'augmenter en premier lieu. La signification de l'utilisation de Gorm est un peu diminuée, mais je l'aimerais lorsque l'on considère le mappage vers Type comme un ORM. Je pense que ce serait bien de ne faire que la partie cartographie par vous-même! !!
Recommended Posts