詳解Go語言如何使用xorm實(shí)現(xiàn)讀取mysql
一、介紹
xorm是go語言的常用orm之一,用來操作數(shù)據(jù)庫。
主要特性特性:
- 支持根據(jù)數(shù)據(jù)庫自動(dòng)生成xorm的結(jié)構(gòu)體
- 支持Struct和數(shù)據(jù)庫表之間的靈活映射, 并支持自動(dòng)同步
- 支持事務(wù)
- 支持使用Id, In, Where, Limit, Join, Having, Table, Sql, Cols等函數(shù)和結(jié)構(gòu)體等方式作為條件
- 支持查詢結(jié)果集導(dǎo)出csv、tsv、xml、json、xlsx、yaml、html功能
二、安裝使用xorm,注意連接的關(guān)閉!
import ( _ "github.com/go-sql-driver/mysql" "xorm.io/xorm" )
然后我們就可以構(gòu)造一個(gè)new方法來初始化使用 orm客戶端了。
我們在下面的代碼,會(huì)通過一個(gè)函數(shù)返回 xorm.EngineInterface,以及一個(gè) engine.Close()函數(shù)供使用者調(diào)用,之所以這樣是因?yàn)?,有些比如腳本腳本之類的
當(dāng)執(zhí)行完,就需要把 mysql連接關(guān)閉掉,以用來節(jié)省連接數(shù)。
如果都不關(guān)閉的話,在高并發(fā)的情況下,連接數(shù)很多,會(huì)把mysql打爆!
type MysqlClient xorm.EngineInterface func NewMysqlClient() (MysqlClient, func(), error) { // 創(chuàng)建 engine 對象 engine, err := xorm.NewEngine("mysql", "user:pwd@tcp(ip:port)/dbname?charset=utf8") if err != nil { fmt.Printf("init engine fail! err:%+v", err) } // 連接池配置 engine.SetMaxOpenConns(30) // 最大 db 連接 engine.SetMaxIdleConns(10) // 最大 db 連接空閑數(shù) engine.SetConnMaxLifetime(30 * time.Minute) // 超過空閑數(shù)連接存活時(shí)間 // 日志相關(guān)配置 engine.ShowSQL(true) // 打印日志 engine.Logger().SetLevel(log.LOG_DEBUG) // 打印日志級別 engine.SetLogger(log.SimpleLogger{}) // 設(shè)置日志輸出 (控制臺, 日志文件, 系統(tǒng)日志等) // 測試連通性 if err = engine.Ping(); err != nil { fmt.Printf("ping to db fail! err:%+v", err) } return engine, func() { engine.Close() }, err }
關(guān)于連接數(shù)的坑以及engine.Close()
engine可以通過engine.Close來手動(dòng)關(guān)閉,但是一般情況下可以不用關(guān)閉,在程序退出時(shí)會(huì)自動(dòng)關(guān)閉。
但是如果,每個(gè)連接都是新建了一個(gè) client的話,一般http服務(wù)不會(huì)退出,如果此時(shí)高并發(fā),就會(huì)增加無數(shù)的mysql連接數(shù),打爆mysql。
在這個(gè)NewMysqlClient函數(shù)里我們創(chuàng)建了一個(gè) 全局的變量 MysqlClient,全局共用一個(gè)連接。
常用方法介紹
engine.SetMaxOpenConns(30) 創(chuàng)建連接池
engine.ShowSQL(true) 在控制臺打印sql語句
engine.Logger().SetLevel(log.LOG_DEBUG) 在控制臺打印調(diào)試及以上的信息
engine.SetLogger(log.DiscardLogger{}) 把日志寫入到文件,或者專門的日志收集系統(tǒng)里。
三、mysql生產(chǎn)struct
使用官方自帶的reverse工具 https://gitea.com/xorm/reverse比如我們現(xiàn)在在有一個(gè)表
CREATE TABLE `user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `name` varchar(45) DEFAULT NULL, `status` smallint(6) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB
我們使用 reverse -f sql_reverse.yaml 來生成 struct
sql_reverse.yaml的代碼如下:
# 步驟1:安裝 go get xorm.io/reverse # 步驟2:修改上面文件中的conn_str以及include_tables的表 # 步驟3:執(zhí)行reverse -f sql_reverse.yaml kind: reverse name: mydb source: database: mysql conn_str: 'user:pasword@tcp(localhost:3306)/test?charset=utf8mb4' targets: - type: codes language: golang include_tables: # 需要生成的表的結(jié)構(gòu) - user //我們要生產(chǎn)的表明 multiple_files: true output_dir: ./internal/domain/flow/repository/po template: | package po {{$ilen := len .Imports}} {{if gt $ilen 0}} import ( {{range .Imports}}"{{.}}"{{end}} ) {{end}} {{range .Tables}} type {{TableMapper .Name}} struct { {{$table := .}} {{range .ColumnsSeq}}{{$col := $table.GetColumn .}} {{ColumnMapper $col.Name}} {{Type $col}} `{{Tag $table $col}}` {{end}} } func (m *{{TableMapper .Name}}) TableName() string { return "{{$table.Name}}" } {{end}} template_path: ./template/goxorm.tmpl # template path for code file, it has higher perior than template field on language
生成對應(yīng)的go代碼為
type User struct { Id int64 `json:"id" xorm:"'id' int(11) not null pk autoincr "` Name string `json:"name" xorm:"'name' varchar(45) null "` Status int64 `json:"status" xorm:"'status' smallint(3) null "` } func (m *User) TableName() string { return "user" }
四、xorm常用操作示例--insert數(shù)據(jù)
4.1 insert 增加1條數(shù)據(jù)
增加一條對象。
engine, _, _ := NewMysqlClient() u := User{ Name: "hisheng", Status: 0, } affected, err := engine.Insert(&u) t.Log(affected, err)
4.2 insert 增加多條數(shù)據(jù)
多條數(shù)據(jù),還是Insert方法,參數(shù)為slice就行。
func TestInsertUsers(t *testing.T) { engine, _, _ := NewMysqlClient() us := []User{{Name: "hi", Status: 1}, {Name: "sheng", Status: 1}} affected, err := engine.Insert(&us) t.Log(affected, err) }
當(dāng)插入多條數(shù)據(jù)的時(shí)候,官方建議我們少于150條數(shù)據(jù),多余150條數(shù)據(jù)的時(shí)候,容易插入失敗。
4.3 insert 增加不同表數(shù)據(jù)
user := new(User) user.Name = "myname" ... questions := make([]Question, 1) questions[0].Content = "whywhywhwy?" affected, err := engine.Insert(user, &questions)
五、xorm常用操作示例--刪除某行
5.1 通過id刪除
user := new(User) affected, err := engine.ID(id).Delete(user)
5.2 通過where條件刪除
user := new(User) affected, err := engine.Where("id = ?",1).Delete(user)
5.3 軟刪除,通過某個(gè)字段實(shí)現(xiàn)軟刪除,比如status=0
這個(gè)用更新的方法
u := User{ Status: 0, } affected, err := engine.Where("id = ?",1).MustCols("status").Update(&u) t.Log(affected, err)
注意這里,增加了一個(gè)MustCols,因?yàn)閤orm默認(rèn)是有值自動(dòng)更新的,而status和默認(rèn)值,是一樣的,默認(rèn)值會(huì)被忽略而不被更新,此時(shí)要更新,需要加一個(gè) MustCols字段。
六、xorm常用操作示例--update更新操作
6.1 以結(jié)構(gòu)體的參數(shù),傳遞要更新的字段
func TestUpdate(t *testing.T) { engine, _, _ := NewMysqlClient() u := User{ Name: "1111", } affected, err := engine.ID(1).Update(&u) }
這個(gè)會(huì)Update的參數(shù)是更新字段。這里會(huì)更新Name字段。
6.2 以map做為參數(shù),傳遞要更新的字段
以map作為要更新的字段,傳遞方式,map的格式為 map[string]interface{}
func TestUpdateMap(t *testing.T) { engine, _, _ := NewMysqlClient() u := map[string]interface{}{"name": "111"} affected, err := engine.ID(1).Update(u) }
6.3指定字段更新,未指定的將不更新,指定了的即使為0也會(huì)更新。
我們通過添加Cols函數(shù)指定需要更新結(jié)構(gòu)體中的值。
affected, err := engine.ID(id).Cols("age").Update(&user)
6.4指定字段更新,未指定的根據(jù)值是否是有值來更新。
有時(shí)候希望能夠指定必須更新某些字段,而其它字段根據(jù)值的情況自動(dòng)判斷,可以使用 MustCols 來組合 Update 使用。
affected, err := engine.ID(id).MustCols("age").Update(&user)
七、xorm常用操作示例--查詢單條
查詢單條數(shù)據(jù)使用Get方法,在調(diào)用Get方法時(shí)需要傳入一個(gè)對應(yīng)結(jié)構(gòu)體的指針,同時(shí)結(jié)構(gòu)體中的非空field自動(dòng)成為查詢的條件和前面的方法條件組合在一起查詢。
7.1 根據(jù)主鍵Id來獲得單條數(shù)據(jù):
user := new(User) has, err := engine.ID(id).Get(user)
7.2 根據(jù)where來獲得單條數(shù)據(jù):
user := new(User) has, err := engine.Where("name=?", "xlw").Get(user)
7.3 根據(jù)user機(jī)構(gòu)體中非空數(shù)據(jù)來獲得單條數(shù)據(jù):
user := &User{Id:1} has, err := engine.Get(user)
八、xorm常用操作示例--查詢多條數(shù)據(jù)
查詢多條數(shù)據(jù)使用Find方法,F(xiàn)ind方法的第一個(gè)參數(shù)為slice的指針或Map指針,即為查詢后返回的結(jié)果,第二個(gè)參數(shù)可選,為查詢的條件struct的指針。
8.1 返回結(jié)果為 結(jié)構(gòu)體slice:
everyone := make([]User, 0) err := engine.Find(&everyone)
8.2 返回結(jié)果為 結(jié)構(gòu)體map:
users := make(map[int64]User) err := engine.Find(&users)
九、xorm常用操作示例--FindAndCount 分頁
FindAndCount 返回結(jié)果為 結(jié)構(gòu)體slice 以及總數(shù):
everyone := make([]User, 0) count,err := engine.Limit(1,20).FindAndCount(&everyone)
十、xorm常用操作示例--事務(wù)操作
func TestTransaction(t *testing.T) { engine, _, _ := NewMysqlClient() session := engine.NewSession() defer session.Close() if err := session.Begin(); err != nil { fmt.Println(err) return } if _, err := session.Insert(&User{Name: "11", Status: 0}); err != nil { fmt.Println(err) _ = session.Rollback() return } _ = session.Commit() }
以上就是詳解Go語言如何使用xorm實(shí)現(xiàn)讀取mysql的詳細(xì)內(nèi)容,更多關(guān)于Go語言 xorm讀取mysql的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
GoLang jwt無感刷新與SSO單點(diǎn)登錄限制解除方法詳解
這篇文章主要介紹了GoLang jwt無感刷新與SSO單點(diǎn)登錄限制解除方法,JWT是一個(gè)簽名的JSON對象,通常用作Oauth2的Bearer token,JWT包括三個(gè)用.分割的部分。本文將利用JWT進(jìn)行認(rèn)證和加密,感興趣的可以了解一下2023-03-03go 原生http web 服務(wù)跨域restful api的寫法介紹
這篇文章主要介紹了go 原生http web 服務(wù)跨域restful api的寫法,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-04-04Golang 使用接口實(shí)現(xiàn)泛型的方法示例
這篇文章主要介紹了Golang 使用接口實(shí)現(xiàn)泛型的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-03-03