日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

Go之XORM操作MySQL

發(fā)布時間:2024/3/24 数据库 46 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Go之XORM操作MySQL 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

創(chuàng)作不易感謝支持。
一條主寫Go和PHP的小菜鳥。平常有時間喜歡自己寫點東西,如有不對的地方,歡迎大佬指點。 個人博客:太陽上的雨天 地址:http://blog.caixiaoxin.cn 善于分享,希望有助他人. 非常感謝各位大佬的關(guān)注和支持

XORM

xorm 一個簡單強大的Go語言O(shè)RM庫。通過它讓操作數(shù)據(jù)庫變得更加簡單。

[XORM操作指南]

XORM關(guān)系映射,只是Go操作數(shù)據(jù)庫的其中之一。比如還有GORM。至于兩者的區(qū)別,一搜一大堆,不再介紹。

這里只介紹一下XORM的基本使用。

導(dǎo)入包

go get -u github.com/go-sql-driver/mysql go get -u github.com/xormplus/xorm

定義結(jié)構(gòu)體

名稱映射規(guī)則

  • 指責(zé)

    結(jié)構(gòu)體名稱 ----- 表名

    結(jié)構(gòu)體字段 ------ 表字段

結(jié)構(gòu)體字段屬性 ----- 對象的表子段屬性

go type’s kindvalue methodxorm type
implemented ConversionConversion.ToDB / Conversion.FromDBText
int, int8, int16, int32, uint, uint8, uint16, uint32Int
int64, uint64BigInt
float32Float
float64Double
complex64, complex128json.Marshal / json.UnMarshalVarchar(64)
[]uint8Blob
array, slice, map except []uint8json.Marshal / json.UnMarshalText
stringVarchar(255)
time.TimeDateTime
cascade structprimary key field valueBigInt
structjson.Marshal / json.UnMarshalText
OthersText
bool1 or 0Bool

前綴映射、后綴映射、緩存映射

通過 core.NewPrefixMapper(core.SnakeMapper{}, “prefix”) 可以創(chuàng)建一個在SnakeMapper的基礎(chǔ)上在命名中添加統(tǒng)一的前綴

例如,如果希望所有的表名都在結(jié)構(gòu)體自動命名的基礎(chǔ)上加一個前綴而字段名不加前綴,則可以在engine創(chuàng)建完成后執(zhí)行以下語句:

tbMapper := core.NewPrefixMapper(core.SnakeMapper{}, "pre_") engine.SetTableMapper(tbMapper)

執(zhí)行之后,結(jié)構(gòu)體 type User struct 默認對應(yīng)的表名就變成了 pre_user 了,而之前默認的是 user

  • 通過 core.NewSufffixMapper(core.SnakeMapper{}, “suffix”) 可以創(chuàng)建一個在SnakeMapper的基礎(chǔ)上在命名中添加統(tǒng)一的后綴
  • 通過 core.NewCacheMapper(core.SnakeMapper{}) 可以創(chuàng)建一個組合了其它的映射規(guī)則,起到在內(nèi)存中緩存曾經(jīng)映射過的命名映射

創(chuàng)建xorm引擎

在xorm里面,可以同時存在多個Orm引擎,一個Orm引擎稱為Engine,一個Engine一般只對應(yīng)一個數(shù)據(jù)庫

db/db.go

package dbimport ("fmt"_ "github.com/go-sql-driver/mysql""github.com/xormplus/xorm" )var engine *xorm.Enginefunc Init() *xorm.Engine {engine, err := xorm.NewEngine("mysql", "root:root@/test?charset=utf8mb4")if err != nil {panic(err)}err = engine.Ping()if err != nil {fmt.Printf("connect ping failed: %v", err)}engine.ShowSQL(true)return engine }

寫入數(shù)據(jù)庫

先創(chuàng)建兩張表,表比較簡單,只是做演示使用

CREATE TABLE `users` (`id` int(11) NOT NULL AUTO_INCREMENT,`username` varchar(100) NOT NULL,`password` varchar(100) NOT NULL,`email` varchar(100) NOT NULL,`created_at` timestamp NULL DEFAULT NULL,`updated_at` timestamp NULL DEFAULT NULL,`deleted_at` timestamp NULL DEFAULT NULL,PRIMARY KEY (`id`),UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;CREATE TABLE `address` (`id` int(11) unsigned NOT NULL AUTO_INCREMENT,`addr` varchar(100) DEFAULT NULL,`created_at` timestamp NULL DEFAULT NULL,`updated_at` timestamp NULL DEFAULT NULL,`deleted_at` timestamp NULL DEFAULT NULL,PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

ORM方式寫入

同一張表的操作

  • 寫入一條數(shù)據(jù)

    type Users struct {Username string `xorm:"username"`Password string `xorm:"password""`Email string `xorm:"email"`CreatedAt time.Time `xorm:"created"`UpdatedAt time.Time `xorm:"updated"`DeletedAt time.Time ` xorm:"deleted"` }func main() {engine := db.Init()u := &Users{}u.Username = "test"u.Password = "123456"u.Email = "test@sina.com"affected, err := engine.Insert(u)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected) }
  • 批量寫入

  • 使用slice

    func main() {engine := db.Init()u := make([]Users, 2)u[0].Username = "test2"u[0].Password = "123456"u[0].Email = "test2@sina.com"u[1].Username = "test3"u[1].Password = "123456"u[1].Email = "test3@sina.com"affected, err := engine.Insert(u)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected) }
  • 使用slice指針批量寫入

    func main() {engine := db.Init()u := make([]*Users, 2)u[0] = &Users{}u[0].Username = "test4"u[0].Password = "123456"u[0].Email = "test4@sina.com"u[1] = &Users{}u[1].Username = "test5"u[1].Password = "123456"u[1].Email = "test5@sina.com"affected, err := engine.Insert(u)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected) }

    多張表的操作

    • 寫入一條記錄

      type Users struct {Username string `xorm:"username"`Password string `xorm:"password""`Email string `xorm:"email"`CreatedAt time.Time `xorm:"created"`UpdatedAt time.Time `xorm:"updated"`DeletedAt time.Time `xorm:"deleted"` }type Address struct {Addr string `xorm:"Addr"`CreatedAt time.Time `xorm:"created"`UpdatedAt time.Time `xorm:"updated"`DeletedAt time.Time `xorm:"deleted"` }func main() {engine := db.Init()u := &Users{}u.Username = "test4"u.Password = "123456"u.Email = "test4@sina.com"a := &Address{}a.Addr = "杭州"affected, err := engine.Insert(u, a)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected) }
    • 批量寫入

      func main() {engine := db.Init()u := make([]*Users, 2)u[0] = &Users{}u[0].Username = "test6"u[0].Password = "123456"u[0].Email = "test4@sina.com"u[1] = &Users{}u[1].Username = "test7"u[1].Password = "123456"u[1].Email = "test5@sina.com"a := make([]*Address, 2)a[0] = &Address{}a[0].Addr = "杭州"a[1] = &Address{}a[1].Addr = "上海"affected, err := engine.Insert(u, a)if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(affected) }

      Note: 這里的多表寫入并沒有使用事務(wù)。如果部分成功,部分失敗不支持回滾

  • 執(zhí)行原生sql寫入數(shù)據(jù)

    func main() {engine := db.Init()sql := "INSERT INTO users(username, password, email) values (?, ?, ?)"res, err := engine.Exec(sql, "original", "123", "123@sina.com")if err != nil {log.Fatal(fmt.Printf("insert into failed, err: %v", err))}fmt.Println(res) }

    Note: 執(zhí)行原生sql寫入數(shù)據(jù),created_at、updated_at時間的值不寫的則為空。

    原生sql寫入還有其余三種方式,這里不再贅述

    刪除數(shù)據(jù)

    ORM方式刪除 - 軟刪除

    在Delete()時,deleted標記的字段將會被自動更新為當(dāng)前時間而不是去刪除該條記錄

    func main() {engine := db.Init()var u = &Users{}u.Username = "test1"affected, err := engine.Delete(u)if err != nil {log.Fatal(fmt.Printf("deleter into failed, err: %v", err))}fmt.Println(affected) }

    執(zhí)行原生sql刪除 - 物理刪除

    func main() {engine := db.Init()sql := "DELETE FROM users where id = ?"affected, err := engine.Exec(sql, 1)if err != nil {log.Fatal(fmt.Printf("deleter into failed, err: %v", err))}fmt.Println(affected) }

    Note: 也可以使用原生sql update更新deleted_at時間為當(dāng)前時間戳,實現(xiàn)軟刪除。

    更新數(shù)據(jù)

    • update方式

      更新數(shù)據(jù)使用engine.Update方法,update的參數(shù)可以是一個結(jié)構(gòu)體指針或者一個Map[string]interface{}類型。

    • 當(dāng)傳入的為結(jié)構(gòu)體指針時,只有非空和0的field才會被作為更新的字段。如果非要更新空字段,需要使用Cols方法顯示指定更新的列
    • 當(dāng)傳入的為Map類型時,key為數(shù)據(jù)庫Column的名字,value為要更新的內(nèi)容。且需要使用engine.Table方法指定表名
    func main() {engine := db.Init()engine.ID(13).Update(&Users{Username: "test"})engine.ID(13).Cols("username", "email").Update(&Users{Username: "test2"}) // 會更新username和email兩個子段,email為空// map類型affected, err := engine.Table(&Users{}).ID(13).Update(map[string]interface{}{"username": "update_original",})if err != nil {log.Fatal(fmt.Printf("update username failed, err: %v", err))}fmt.Println(affected) }
    • 執(zhí)行原生sql更新數(shù)據(jù)

      func main() {engine := db.Init()sql := "UPDATE users SET username = ?, updated_at = ? WHERE id = ?"res, err := engine.Exec(sql, "aaa", time.Now().Format("2006-01-02 15:04:05"), 13)if err != nil {log.Fatal(fmt.Printf("update username failed, err: %v", err))}fmt.Println(res) }

    查詢數(shù)據(jù)

    ORM

  • 查詢一條數(shù)據(jù) - GET方法

    func main() {engine := db.Init()// SELECT * FROM user LIMIT 1user1 := &Users{}has, _ := engine.ID(1).Get(user1)if has {fmt.Printf("user1:%v\n", user1)}// SELECT * FROM user WHERE name = ? ORDER BY id DESC LIMIT 1user2 := &Users{}has, _ = engine.Where("username = ?", "aaa").Desc("id").Get(user2)if has {fmt.Printf("user1:%v\n", user1)} }
  • 查詢多條數(shù)據(jù) - Find 方法

  • Find()需要傳入對象切片的指針或 map 的指針

    func main() {engine := db.Init()slicUsers := make([]Users, 0)_ = engine.Find(&slicUsers)fmt.Println(slicUsers)mapUsers := make([]Users, 0)engine.Where("username = ?", "aaa").Find(&mapUsers)fmt.Println(mapUsers) }
  • Iterate 效果與Find方法一樣,對了一個回調(diào)函數(shù)處理每條記錄

    func main() {engine := db.Init()engine.Where("username = ?", "aaa").Iterate(new(Users), func(i int, bean interface{}) error {users := bean.(*Users)fmt.Println(users)return nil}) }
  • Count 統(tǒng)計滿足條件的數(shù)量,參數(shù)為struct指針

    func main() {engine := db.Init()count, _ := engine.Where("length(username) > ?", 3).Count(&Users{})fmt.Println(count) }
  • Rows方法 和 Iterate方法類似。

    func main() {engine := db.Init()u := &Users{}rows, _ := engine.Where("id > ?", 5).Rows(u)defer rows.Close()for rows.Next() {rows.Scan(u)fmt.Println(u)} }
  • 原生sql查詢

    寫sql語句,然后執(zhí)行即可。和更新刪除類似,不再贅述。

    總結(jié)

    以上是生活随笔為你收集整理的Go之XORM操作MySQL的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。