↵
上一篇教程我們了解到了基礎的GO文法,今天我們來學習如何使用GO開發一個通用的mysql管理器,下面就直接進入步驟環節,代碼需要承接上一篇教程的,如有疑問請檢視上一篇教程
技術版權歸屬
廣州市金獅網絡科技有限公司 (https://kingc.cn/),如需商用請聯系公司
1. 編寫一個多資料源執行個體的管理器對象,以及改造下之前的DBConfig對象
// 連接配接管理器
type RDBManager struct {
OpenTx bool // 是否開啟事務
DsName string // 資料源名稱
Db *sql.DB // 非事務執行個體
Tx *sql.Tx // 事務執行個體
Errors []error // 操作過程中記錄的錯誤
}
// 資料庫配置
type DBConfig struct {
DsName string // 資料源名稱
Host string // 位址IP
Port int // 資料庫端口
Database string // 資料庫名稱
Username string // 賬号
Password string // 密碼
}
2. 編寫初始化多個資料源配置的方法,并改造下我們之前的NewMysql方法
// 初始化資料庫執行個體
func NewMysql(conf DBConfig) (*sql.DB, error) {
// 定義占位符字元串,使用配置值替換%s和%d
link := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8", conf.Username, conf.Password, conf.Host, conf.Port, conf.Database)
// 打開mysql獲得執行個體對象
db, err := sql.Open("mysql", link)
// 打開mysql失敗,傳回nil對象,以及傳回err對象
if err != nil {
return nil, errors.New("mysql初始化失敗: " + err.Error())
}
// 打開mysql成功傳回db對象,err=nil
return db, nil
}
var (
MASTER = "MASTER" // 預設主資料源
RDBs = map[string]*RDBManager{} // 初始化時加載資料源到集合
)
// 初始化多個資料庫配置檔案
func BuildByConfig(input ...DBConfig) {
if len(input) == 0 {
panic("資料源配置不能為空")
}
for _, v := range input {
db, err := NewMysql(v)
panic(err)
if len(v.DsName) == 0 {
v.DsName = MASTER
}
rdb := &RDBManager{
Db: db,
DsName: v.DsName,
}
RDBs[v.DsName] = rdb
}
}
3. 編寫擷取資料源的方法,包含是否開啟事務,資料源名稱參數
// 擷取資料源,并控制是否開啟事務
func GetDB(openTx bool, ds ...string) (*RDBManager, error) {
dsName := MASTER
if len(ds) > 0 && len(ds[0]) > 0 {
dsName = ds[0]
}
rt := RDBs[dsName]
rdb := &RDBManager{
OpenTx: openTx,
Db: rt.Db,
DsName: rt.DsName,
Errors: []error{},
}
// 如設定事務,則初始化事務執行個體
if rdb.OpenTx {
tx, err := rdb.Db.Begin()
if err != nil {
return nil, errors.New("開啟事務失敗:" + err.Error())
}
rdb.Tx = tx
}
return rdb, nil
}
4. 編寫釋放資料庫資源,并送出事務的方法
// 釋放資源并送出事務
func (self *RDBManager) Close() {
if self.OpenTx { // 開啟事務操作邏輯
if len(self.Errors) > 0 { // 如産生異常則復原事務
self.Tx.Rollback()
} else {
self.Tx.Commit() // 如無異常則送出事務
}
}
}
5. 使用擷取的資料源進行儲存資料操作,我們改造下之前的CRUD方法
// 通過管理器開啟事務儲存資料
func (self *RDBManager) CRUD1() error {
// 編寫需要執行的sql
createSql := "insert test_user(username, password, age, sex) values(?,?,?,?)"
// 預編譯sql,事務模式
stmt, err := self.Tx.Prepare(createSql)
if err != nil {
return errors.New("預編譯失敗: " + err.Error())
}
// 送出編譯sql對應參數
ret, err := stmt.Exec("zhangsan", "123456", 18, 1)
if err != nil {
return errors.New("送出資料失敗: " + err.Error())
}
// 儲存成功後擷取自增ID
fmt.Println(ret.LastInsertId())
return nil
}
6. 編寫單元測試用例
// 單元測試
func TestCRUD1(t *testing.T) {
// 資料源配置
conf := DBConfig{
DsName: "test",
Host: "127.0.0.1",
Port: 3306,
Database: "test",
Username: "root",
Password: "123456",
}
// 初始化資料源
BuildByConfig(conf)
// 擷取test資料源
rdb, err := GetDB(true, "test")
if err != nil {
panic(err)
}
// 釋放資源
defer rdb.Close()
// 執行儲存資料方法
if err := rdb.CRUD1(); err != nil {
panic(err)
}
}
上面我們已經明白了自定義資料源管理器如何實作,通過示例示範操作,下一篇文章我會講解如何封裝對象轉sql入庫,敬請期待!