gorm增删改查总结

gorm在创建表时使用CreateTable方法进行处理,其参数可以是结构体变量的地址形式,也可以是结构体的地址形式。

例如:

var t Tecent

db.CreateTable(&t)或者db.CreateTable(&Tecent{})。即使类的地址形式中初始化了一些字段,在创建表之后也不会自动添加到表中。如果表已经创建并且表中有数据,再次执行该方法不会再次创建表也不会清除数据。

同理,在创建插入数据时一样可以使用结构体变量地址或者结构体自身的实例化。其实直接使用变量本身也没问题,只不过有些回调函数是使用指针类型调用的,那么就无法调用了。

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

在插入数据操作时,如果插入数据表的主键为空那么在插入操作后可以使用NewRecord方法判断是否成功,但是如果插入之前就给主键赋值,那该方法就无法判断是否插入成功。因为该方法只是判断主键是否为空。

[plain]  view plain  copy
  1. type Nxin struct {  
  2.     Cid int `gorm:"primary_key""`  
  3.     Cname string  
  4.     Caddress string  
  5. }  
[plain]  view plain  copy
  1. nn:=Nxin{2,"xiaodai","17ceng"}  
  2. fmt.Println(db.NewRecord(nn))  
  3. er:=db.Create(&nn)  
  4. fmt.Println(db.NewRecord(nn))  
  5. if er.Error!=nil{  
  6.     panic("primary key is existing")  
  7. }  
返回的结果都是为false,表示主键不为空。

gorm的文档中提供了一个回调函数BeforeCreate,这个方法可以在插入数据之前调用,如果在这个方法调用之前列已经赋值,那么该方法会覆盖掉原来的值。前提是该方法的调用者是指针类型。


扫描二维码关注公众号,回复: 871992 查看本文章

删除操作与其他语言的orm的删除不同,默认的删除方式是软删除,只是修改了字段delete_at字段为当前时间,然后在查询时再也查不到,但是在数据库中依然存在。如果模型继承自gorm.Model,那么Delete方法则软删除,如果不继承那么就是硬删除(清空数据)。

db.Delete(&Nxin{})是删除表中所有的数据。但是是硬删除。Nxin结构体不继承自gorm.Model。
db.Delete(&Dbn{}})软删除。

匹配删除有两种方式:

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

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


修改数据的方式有很多种,以下一一列出比较常见的几种方式:

第一种,先查询在修改最后保存。

[plain]  view plain  copy
  1. var nxi Nxin  
  2. db.First(&nxi)  
  3. nxi.Caddress="biejing"  
  4. db.Save(&nxi)  
查询到的数据复制到nxi变量中,然后修改保存。

但是这个方法无法完美的在继承自gorm.Model的结构体中使用。如果对该类型的struct修改,就会导致表中create_at等字段被重置。目前我还没办法解决这个问题,希望有解决办法的读者下面留言告诉我,多谢。

第二种,更新表中所有记录某个字段的值。直接针对某个表的模型进行操作,然后更新。

[plain]  view plain  copy
  1. db.Model(&Nxin{}).Update("caddress","jp")  
第三种,匹配更新。也就是对符合条件的数据进行更新。方法比较多,可以参考注释内容。还有其他的方式没有一一列举,不过这些方法已经可以满足平时需要,gorm的文档中提供的其他方法也多数是锦上添花。
[plain]  view plain  copy
  1. <span style="white-space:pre;"> </span>db.Model(&Nxin{}).Where("cid=?",26).Update("caddress","china")//条件写在where里面  
[plain]  view plain  copy
  1. <span style="white-space:pre;"> </span>db.Model(&Nxin{}).Where("cid in (?)",[]int{10,11}).Update("caddress","haidian")  
  2.     db.Where("cid=?",37).Model(&Nxin{}).Update("caddress","korean")//where与model先后顺序对结果没影响  
  3.     db.Where("cid=?",38).Update("caddress","englist").Model(&Nxin{})//但是model不能放在最后  
  4.   
  5.     var nnn Nxin  
  6.     nnn=Nxin{Cid:17}//初始化的时候给某些字段赋值,更新时可以直接作为查询匹配条件的记录,然后修改。  
  7.     db.Model(&nnn).Update("caddress","franch")  
  8.     db.Model(nnn).Update("caddress","german")//此处可以看到地址类型与变量类型对结果没有影响  
  9.     db.Model(&nnn).Update(map[string]interface{}{"cname":"newtest","caddress":"italy"})//同时修改多个字段  
  10.     db.Model(&nnn).Update(Nxin{Cname:"nxin",Caddress:"haidian"})  
在对表字段更新时可以使用map保存要修改的值,也可以使用结构体类型,但是二者的区别在于如果使用struct更改,那么对某个字段设置成“”,0,false等就不起作用。也就是说:

[plain]  view plain  copy
  1. db.Model(&nnn).Update(map[string]interface{}{"cname":"newtest","caddress":"italy"})//caddress被设置成italy  
  2. db.Model(&nnn).Update(Nxin{Cname:"nxin",Caddress:""})//此处caddress的值并没有被修改成""  
  3. db.Model(&nnn).Update(map[string]interface{}{"cname":"newtest","caddress":""})//caddress被设置成""  


查询

第一种,根据gorm自带first,last方法查询。

[plain]  view plain  copy
  1. <span style="white-space:pre;"> </span>var nx Nxin  
  2.     nx=Nxin{Cid:19}//查询的条件可以直接写在结构体对象里面  
  3.     //db.First(&nx)  
  4.     //fmt.Println(nx.Caddress)  
  5.     db.First(&nx)  
  6.     fmt.Println(nx.Caddress)  
可以把查询条件写在struct的变量里,但是因为first,last这些方法只返回一个附个条件的记录。所以可以使用find方法返回多个记录。

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

将返回的值放在nx2数组里。这种办法无法把查询条件写在结构体变量里了,只能写在where里。

 
 
[plain]  view plain  copy
  1. <span style="white-space:pre;"> </span>var nx3 Nxin  
  2.     nx3=Nxin{Cid:20}  
  3.     db.Where("caddress=?","dd").Find(&nx3)  
[plain]  view plain  copy
  1. <span style="white-space:pre;"> </span>db.Find(&nx3)//select * from nxins where cid=20  
[plain]  view plain  copy
  1. <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
  1. <span style="white-space:pre;"> </span>db.Find(&nx3,map[string]interface{}{"caddress":"wang",cname:"wang"})  
[plain]  view plain  copy
  1. <span style="white-space:pre;"> </span>db.Find(&nx3,"caddress=? and cname=?","bj","wang")  
[plain]  view plain  copy
  1. fmt.Println(nx3)  

这种方式为在变量中添加条件,where中再添加一条条件,那么就相当于使用and把两个条件合并。即cid=20 and caddress=dd


[plain]  view plain  copy
  1. <span style="white-space:pre;"> </span>var nx3 Nxin  
  2.     nx3=Nxin{Cid:20}  
  3.     db.Where("caddress=?","dd").Find(&nx3)  
  4.     fmt.Println(nx3)  
  5.     var nx4 Nxin  
  6.     db.Where(&Nxin{Cid:32,Caddress:"jp"}).First(&nx4)  
  7.     fmt.Println(nx4)  
  8.     var nx5 []Nxin  
  9.     defer db.Close()  
  10.     db.Where(map[string]interface{}{"caddress":"jp"}).Find(&nx5)  
  11.     fmt.Println(nx5)  
在where语句中可以使用map类型或者struct类型进行查询条件添加,但是添加的条件都是and连接。注意:nx5要接受的结果集是很多条数据,但是nx5如果是Nxin类型而不是数组,那么nx5就只会获取最后一条数据。


与where条件类似的还有Not条件语句。如果使用or作为查询条件,那么就要使用or语句了,不过Or语句的用法与where一样,只不过在生成的sql语句中使用的or连接,


[plain]  view plain  copy
  1. var nx6 []Nxin  
  2. db.Where(map[string]interface{}{"caddress":"jp3"}).Or(map[string]interface{}{"cid":56}).Find(&nx6)  
  3. fmt.Println(nx6)  
  4. var nx7 []Nxin  
  5. db.Or(map[string]interface{}{"cid":56}).Where(map[string]interface{}{"caddress":"jp3"}).Find(&nx7)  
  6. fmt.Println(nx7)  
or与where的先后顺序不影响结果的查询。

一些小的查询技巧:

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)//获取表数据行数


对一些复杂业务进行查询时,可以使用join进行连接。

db.Table("users").Select("users.name, emails.email").Joins("left join emails on emails.user_id = users.id").Scan(&results)
对于已经获取的结果,应该保存在一个结构体的变量中。


如果只是想获得某个表中某个字段的值可以使用Pluck方法。但是返回的结果必须存放在数组中。

var age []int

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


如果使用model类型进行查询,那么结果会自动填写到类似&user之类的变量中。但是如果使用

db.Table("user")。。。。。。这种类型,结果需要使用scan方法赋值到对应的参数变量中。

猜你喜欢

转载自blog.csdn.net/zl1zl2zl3/article/details/80197433