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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

gorm增删改查总结

發(fā)布時間:2025/3/21 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 gorm增删改查总结 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

gorm在創(chuàng)建表時使用CreateTable方法進行處理,其參數(shù)可以是結(jié)構(gòu)體變量的地址形式,也可以是結(jié)構(gòu)體的地址形式。

例如:

var t Tecent

db.CreateTable(&t)或者db.CreateTable(&Tecent{})。即使類的地址形式中初始化了一些字段,在創(chuàng)建表之后也不會自動添加到表中。如果表已經(jīng)創(chuàng)建并且表中有數(shù)據(jù),再次執(zhí)行該方法不會再次創(chuàng)建表也不會清除數(shù)據(jù)。

同理,在創(chuàng)建插入數(shù)據(jù)時一樣可以使用結(jié)構(gòu)體變量地址或者結(jié)構(gòu)體自身的實例化。其實直接使用變量本身也沒問題,只不過有些回調(diào)函數(shù)是使用指針類型調(diào)用的,那么就無法調(diào)用了。

db.Create(&Tecent{id:1,name:"csdn"})

在插入數(shù)據(jù)操作時,如果插入數(shù)據(jù)表的主鍵為空那么在插入操作后可以使用NewRecord方法判斷是否成功,但是如果插入之前就給主鍵賦值,那該方法就無法判斷是否插入成功。因為該方法只是判斷主鍵是否為空。

?

[plain]?view plain?copy

  • type?Nxin?struct?{??
  • ????Cid?int?`gorm:"primary_key""`??
  • ????Cname?string??
  • ????Caddress?string??
  • }??
  • [plain]?view plain?copy

  • nn:=Nxin{2,"xiaodai","17ceng"}??
  • fmt.Println(db.NewRecord(nn))??
  • er:=db.Create(&nn)??
  • fmt.Println(db.NewRecord(nn))??
  • if?er.Error!=nil{??
  • ????panic("primary?key?is?existing")??
  • }??
  • 返回的結(jié)果都是為false,表示主鍵不為空。

    ?

    gorm的文檔中提供了一個回調(diào)函數(shù)BeforeCreate,這個方法可以在插入數(shù)據(jù)之前調(diào)用,如果在這個方法調(diào)用之前列已經(jīng)賦值,那么該方法會覆蓋掉原來的值。前提是該方法的調(diào)用者是指針類型。

    ?

    刪除操作與其他語言的orm的刪除不同,默認的刪除方式是軟刪除,只是修改了字段delete_at字段為當前時間,然后在查詢時再也查不到,但是在數(shù)據(jù)庫中依然存在。如果模型繼承自gorm.Model,那么Delete方法則軟刪除,如果不繼承那么就是硬刪除(清空數(shù)據(jù))。

    db.Delete(&Nxin{})是刪除表中所有的數(shù)據(jù)。但是是硬刪除。Nxin結(jié)構(gòu)體不繼承自gorm.Model。
    db.Delete(&Dbn{}})軟刪除。

    匹配刪除有兩種方式:

    db.Where("cid=?",8).Delete(&Nxin{})

    db.Delete(&Nxin{},"cid=?",9)

    ?

    修改數(shù)據(jù)的方式有很多種,以下一一列出比較常見的幾種方式:

    第一種,先查詢在修改最后保存。

    ?

    [plain]?view plain?copy

  • var?nxi?Nxin??
  • db.First(&nxi)??
  • nxi.Caddress="biejing"??
  • db.Save(&nxi)??
  • 查詢到的數(shù)據(jù)復(fù)制到nxi變量中,然后修改保存。

    ?

    但是這個方法無法完美的在繼承自gorm.Model的結(jié)構(gòu)體中使用。如果對該類型的struct修改,就會導(dǎo)致表中create_at等字段被重置。目前我還沒辦法解決這個問題,希望有解決辦法的讀者下面留言告訴我,多謝。

    第二種,更新表中所有記錄某個字段的值。直接針對某個表的模型進行操作,然后更新。

    ?

    [plain]?view plain?copy

  • db.Model(&Nxin{}).Update("caddress","jp")??
  • 第三種,匹配更新。也就是對符合條件的數(shù)據(jù)進行更新。方法比較多,可以參考注釋內(nèi)容。還有其他的方式?jīng)]有一一列舉,不過這些方法已經(jīng)可以滿足平時需要,gorm的文檔中提供的其他方法也多數(shù)是錦上添花。

    ?

    [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>db.Model(&Nxin{}).Where("cid=?",26).Update("caddress","china")//條件寫在where里面??
  • [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>db.Model(&Nxin{}).Where("cid?in?(?)",[]int{10,11}).Update("caddress","haidian")??
  • ????db.Where("cid=?",37).Model(&Nxin{}).Update("caddress","korean")//where與model先后順序?qū)Y(jié)果沒影響??
  • ????db.Where("cid=?",38).Update("caddress","englist").Model(&Nxin{})//但是model不能放在最后??
  • ??
  • ????var?nnn?Nxin??
  • ????nnn=Nxin{Cid:17}//初始化的時候給某些字段賦值,更新時可以直接作為查詢匹配條件的記錄,然后修改。??
  • ????db.Model(&nnn).Update("caddress","franch")??
  • ????db.Model(nnn).Update("caddress","german")//此處可以看到地址類型與變量類型對結(jié)果沒有影響??
  • ????db.Model(&nnn).Update(map[string]interface{}{"cname":"newtest","caddress":"italy"})//同時修改多個字段??
  • ????db.Model(&nnn).Update(Nxin{Cname:"nxin",Caddress:"haidian"})??
  • 在對表字段更新時可以使用map保存要修改的值,也可以使用結(jié)構(gòu)體類型,但是二者的區(qū)別在于如果使用struct更改,那么對某個字段設(shè)置成“”,0,false等就不起作用。也就是說:

    ?

    ?

    [plain]?view plain?copy

  • db.Model(&nnn).Update(map[string]interface{}{"cname":"newtest","caddress":"italy"})//caddress被設(shè)置成italy??
  • db.Model(&nnn).Update(Nxin{Cname:"nxin",Caddress:""})//此處caddress的值并沒有被修改成""??
  • db.Model(&nnn).Update(map[string]interface{}{"cname":"newtest","caddress":""})//caddress被設(shè)置成""??
  • ?

    查詢

    第一種,根據(jù)gorm自帶first,last方法查詢。

    [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>var?nx?Nxin??
  • ????nx=Nxin{Cid:19}//查詢的條件可以直接寫在結(jié)構(gòu)體對象里面??
  • ????//db.First(&nx)??
  • ????//fmt.Println(nx.Caddress)??
  • ????db.First(&nx)??
  • ????fmt.Println(nx.Caddress)??
  • 可以把查詢條件寫在struct的變量里,但是因為first,last這些方法只返回一個附個條件的記錄。所以可以使用find方法返回多個記錄。

    ?

    ?

    [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>var?nx2?[]Nxin??
  • ????db.Where("cid?in?(?)",[]int{18,19}).Find(&nx2)??
  • ????fmt.Println(nx2)??

  • 將返回的值放在nx2數(shù)組里。這種辦法無法把查詢條件寫在結(jié)構(gòu)體變量里了,只能寫在where里。

    ?

    ?

    ?

    ?

    ?

    [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>var?nx3?Nxin??
  • ????nx3=Nxin{Cid:20}??
  • ????db.Where("caddress=?","dd").Find(&nx3)??
  • [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>db.Find(&nx3)//select?*?from?nxins?where?cid=20??
  • [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>db.Find(&nx3,Nxin{caddress:"jp"})//select?*?from?nxins?where?cid=20?and?caddress="jp"??
  • [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>db.Find(&nx3,map[string]interface{}{"caddress":"wang",cname:"wang"})??
  • [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>db.Find(&nx3,"caddress=??and?cname=?","bj","wang")??
  • [plain]?view plain?copy

  • fmt.Println(nx3)??
  • ?

    這種方式為在變量中添加條件,where中再添加一條條件,那么就相當于使用and把兩個條件合并。即cid=20 and caddress=dd

    ?

    ?

    ?

    [plain]?view plain?copy

  • <span?style="white-space:pre;">?</span>var?nx3?Nxin??
  • ????nx3=Nxin{Cid:20}??
  • ????db.Where("caddress=?","dd").Find(&nx3)??
  • ????fmt.Println(nx3)??
  • ????var?nx4?Nxin??
  • ????db.Where(&Nxin{Cid:32,Caddress:"jp"}).First(&nx4)??
  • ????fmt.Println(nx4)??
  • ????var?nx5?[]Nxin??
  • ????defer?db.Close()??
  • ????db.Where(map[string]interface{}{"caddress":"jp"}).Find(&nx5)??
  • ????fmt.Println(nx5)??
  • 在where語句中可以使用map類型或者struct類型進行查詢條件添加,但是添加的條件都是and連接。注意:nx5要接受的結(jié)果集是很多條數(shù)據(jù),但是nx5如果是Nxin類型而不是數(shù)組,那么nx5就只會獲取最后一條數(shù)據(jù)。


    與where條件類似的還有Not條件語句。如果使用or作為查詢條件,那么就要使用or語句了,不過Or語句的用法與where一樣,只不過在生成的sql語句中使用的or連接,

    ?

    ?

    ?

    [plain]?view plain?copy

  • var?nx6?[]Nxin??
  • db.Where(map[string]interface{}{"caddress":"jp3"}).Or(map[string]interface{}{"cid":56}).Find(&nx6)??
  • fmt.Println(nx6)??
  • var?nx7?[]Nxin??
  • db.Or(map[string]interface{}{"cid":56}).Where(map[string]interface{}{"caddress":"jp3"}).Find(&nx7)??
  • fmt.Println(nx7)??
  • or與where的先后順序不影響結(jié)果的查詢。

    ?

    ?

    一些小的查詢技巧:

    ?

    ?

    db.Limit(10).where()....//限制只去前10個記錄,相當于select * from xxx limit 10

    db.Select("name,age").Find(&user)//只查詢name,age字段,相當于select name,age from user

    db.Select([]string{"name","age"}).Find(&user)

    var c int

    db.Model(&User{}).Count(&c)//獲取表數(shù)據(jù)行數(shù)

    ?

    對一些復(fù)雜業(yè)務(wù)進行查詢時,可以使用join進行連接。

    ?

    db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)

    對于已經(jīng)獲取的結(jié)果,應(yīng)該保存在一個結(jié)構(gòu)體的變量中。

    ?

    ?

    如果只是想獲得某個表中某個字段的值可以使用Pluck方法。但是返回的結(jié)果必須存放在數(shù)組中。

    var age []int

    db.Model(&User{}).Pluck("age",&age)

    ?

    如果使用model類型進行查詢,那么結(jié)果會自動填寫到類似&user之類的變量中。但是如果使用

    db.Table("user")。。。。。。這種類型,結(jié)果需要使用scan方法賦值到對應(yīng)的參數(shù)變量中。

    《新程序員》:云原生和全面數(shù)字化實踐50位技術(shù)專家共同創(chuàng)作,文字、視頻、音頻交互閱讀

    總結(jié)

    以上是生活随笔為你收集整理的gorm增删改查总结的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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