最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解Go語言如何使用xorm實(shí)現(xiàn)讀取mysql

 更新時(shí)間:2022年11月17日 10:35:20   作者:海生  
xorm是go語言的常用orm之一,可以用來操作數(shù)據(jù)庫。本文就來和大家聊聊Go語言如何使用xorm實(shí)現(xiàn)讀取mysql功能,感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

一、介紹

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客戶端了。

我們?cè)谙旅娴拇a,會(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 對(duì)象
    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) // 打印日志級(jí)別
    engine.SetLogger(log.SimpleLogger{})    // 設(shè)置日志輸出 (控制臺(tái), 日志文件, 系統(tǒng)日志等)

    // 測(cè)試連通性
    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) 在控制臺(tái)打印sql語句

engine.Logger().SetLevel(log.LOG_DEBUG) 在控制臺(tái)打印調(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

生成對(duì)應(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ù)

增加一條對(duì)象。

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è)對(duì)應(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的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 解決go在函數(shù)退出后子協(xié)程的退出問題

    解決go在函數(shù)退出后子協(xié)程的退出問題

    這篇文章主要介紹了解決go在函數(shù)退出后子協(xié)程的退出問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2021-04-04
  • GoLang?channel關(guān)閉狀態(tài)相關(guān)操作詳解

    GoLang?channel關(guān)閉狀態(tài)相關(guān)操作詳解

    Channel?和?goroutine?的結(jié)合是?Go?并發(fā)編程的大殺器。而?Channel?的實(shí)際應(yīng)用也經(jīng)常讓人眼前一亮,通過與?select,cancel,timer?等結(jié)合,它能實(shí)現(xiàn)各種各樣的功能。接下來,我們就要介紹GoLang?channel關(guān)閉狀態(tài)相關(guān)操作
    2022-10-10
  • Go語言并發(fā)之原子操作詳解

    Go語言并發(fā)之原子操作詳解

    代碼中的加鎖操作因?yàn)樯婕皟?nèi)核態(tài)的上下文切換會(huì)比較耗時(shí)、代價(jià)比較高。針對(duì)基本數(shù)據(jù)類型我們還可以使用原子操作來保證并發(fā)安全,本文就來和大家詳細(xì)聊聊,需要的可以參考下
    2022-12-12
  • Golang 數(shù)據(jù)庫操作(sqlx)和不定字段結(jié)果查詢

    Golang 數(shù)據(jù)庫操作(sqlx)和不定字段結(jié)果查詢

    本文主要介紹了Golang 數(shù)據(jù)庫操作(sqlx)和不定字段結(jié)果查詢,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • 一文吃透Go的內(nèi)置RPC原理

    一文吃透Go的內(nèi)置RPC原理

    這篇文章主要為大家詳細(xì)介紹了Go語言中內(nèi)置RPC的原理。說起?RPC?大家想到的一般是框架,Go?作為編程語言竟然還內(nèi)置了?RPC,著實(shí)讓我有些吃鯨,本文就來一起聊聊吧
    2023-03-03
  • Go語言實(shí)現(xiàn)逐行讀取和寫入文件詳解

    Go語言實(shí)現(xiàn)逐行讀取和寫入文件詳解

    這篇文章主要介紹了如何使用go語言實(shí)現(xiàn)從輸入文件中讀取每行數(shù)據(jù),然后將每行字段組合成SQL插入腳本,然后逐行寫入另外一個(gè)空白文件中,有需要的可以參考下
    2024-01-01
  • Go?gRPC服務(wù)雙向流式RPC教程

    Go?gRPC服務(wù)雙向流式RPC教程

    這篇文章主要為大家介紹了Go?gRPC服務(wù)雙向流式RPC教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-06-06
  • golang panic及處理機(jī)制

    golang panic及處理機(jī)制

    Go語言追求簡(jiǎn)潔優(yōu)雅,所以,Go語言不支持傳統(tǒng)的 try…catch…finally 這種異常,因?yàn)镚o語言的設(shè)計(jì)者們認(rèn)為,將異常與控制結(jié)構(gòu)混在一起會(huì)很容易使得代碼變得混亂,今天給大家介紹golang panic及處理機(jī)制,需要的朋友參考下吧
    2021-08-08
  • golang實(shí)現(xiàn)ping命令的完整代碼

    golang實(shí)現(xiàn)ping命令的完整代碼

    這篇文章給大家介紹了如何使用golang實(shí)現(xiàn)ping命令,文中給大家介紹了完整的實(shí)現(xiàn)代碼,并有詳細(xì)的圖文講解,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-02-02
  • Go 語言 JSON 標(biāo)準(zhǔn)庫的使用

    Go 語言 JSON 標(biāo)準(zhǔn)庫的使用

    今天通過本文給大家介紹Go 語言 JSON 標(biāo)準(zhǔn)庫的使用小結(jié),包括序列化和反序列化的相關(guān)知識(shí),感興趣的朋友跟隨小編一起看看吧
    2021-10-10

最新評(píng)論

体育| 平阳县| 崇礼县| 玛纳斯县| 灯塔市| 南京市| 彝良县| 辉县市| 绵阳市| 乌兰察布市| 松滋市| 阿拉尔市| 井研县| 北宁市| 稷山县| 宽甸| 敦化市| 宝坻区| 航空| 嘉禾县| 洛浦县| 五家渠市| 丽江市| 江西省| 和顺县| 阜康市| 岳普湖县| 衡东县| 宁波市| 息烽县| 清镇市| 开远市| 许昌县| 固安县| 即墨市| 全南县| 桓仁| 秀山| 怀柔区| 凤凰县| 长乐市|