首页 > 其他分享 >[GO语言tips05]浅谈GORM常用方法

[GO语言tips05]浅谈GORM常用方法

时间:2023-03-12 14:13:49浏览次数:45  
标签:浅谈 db tips05 修改 User GO First Find Delete

0. 引言

GORM就是通过Go语言直接使用封装好的SQL语句,在使用的时候很多方法,那到底这些东西是如何执行的。主要说一下常见的几个CRUD方法。

1. 连接数据库

使用的是gorm.Open参数第一个是用mysql打开数据库(参数是数据库的相关信息),第二个参数是使用gorm的一些参数,一般来说是不需要修改的。

dsn := "root:123456@tcp(127.0.0.1:3306)/gorm?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})

2. AutoMigrate

这个方法是用来给把表和结构体连接起来的。

db.AutoMigrate(&User{})这样一来,如果没有users表就会创建一个,如果有也会再添加上原表没有的列。

里面的参数是地址&User{}

这样一来就可以直接通过db对表和结构体进行操作了。

3. CRUD

3.1 增

3.1.1 CREATE

因为是创建一条信息,所以需要创建一个实例然后设定参数,最后作为参数使用Create方法,这样就会把实例所携带的信息添加到users表中。

// 方法一:
u := new(User)
u.Name = "Fire"
u.Age = 18
db.Create(u)
// 方法二:
db.Create(&User{Name: "Fire",Age: 18})

那既然如此,如果我传递的参数带了多条信息会发生什么?也就是说我传递的是一个User的切片:

u := []User{{Name: "f1", Age: 19}, {Name: "f2", Age: 29}}
db.Create(&u)

navicat_1d0jmTDkXs.png

wow,可以发现两条都添加成功了,说明Create是把实例所带的信息全部给创建到表中。

3.2 查

3.2.1 First

这个方法是返回表单中满足条件的第一条信息

很容易理解的,至于如何使用,直接把一个空实例放进去即可:

// 方法一:
u := new(User)
db.First(&u1)
// 方法二:
db.First(&User{})

第二种方法属于是匿名查询了,因为这个函数会把查询到的内容直接修改到参数中(这也是为什么要取地址的原因,结构体是默认值传递),之后可以打印这个参数看一下。

为什么说是满足条件的第一条信息而不是第一条信息呢,因为First实际上是可以带参数的,只是默认条件下返回表单中第一条:

// 形式一:
db.First(&User{},"name = ?","firecar")
// 形式二:
db.Where("name = ?", "firecar2").First(&u1)

实际上两种形式是等价的,相当于一个条件查询。

那如果说,我作为参数的实例携带了信息会是什么效果呢?让我们做一个简单的测试:

//db.First(&User{Name: "f1", Age: 19})
u := User{Name: "f1", Age: 19}
db.First(&u)

最后得到的结果是——返回的是表单中的第一条信息。

也就是说通过这个方法你传递的实例是否携带信息是无关紧要的事情(不关心你个人怎么样,只关心你整个家族),这么说来这个方法还挺薄情

3.2.2 Find

Find这个方法就更有意思了。

Find使用和First是一模一样的,只不过它会返回所有满足条件的信息而First只返回一条,当Find没有其他参数时默认返回所有信息:

u := User{}
db.Find(&u)

上面的代码理论上是会返回所有的信息,但是如果你的参数是一个而不是切片,他只会返回第一条信息(返回到参数里,参数是一个就只能存一个),如:

u1 := User{}
db.Find(&u1) // u1只会存第一条信息

u2 := []User{}
db.Find(&u2) // u2会存储所有信息

至于Find的条件查询也和First一样,如果传进来的参数有信息,也会被查询给覆盖掉,因此,参数有没有信息都无所谓。

3.3 改

3.3.1 Save

修改(更新)总得有个修改的对象,因此修改是要依托于之前的查询的。

u := new(User)
db.First(u)
u.Name = "hyc"
db.Save(u)

上面是最基础的改法,查询到要修改的参数,然后直接进行修改,之后使用Save来保存即可。

那我如果这样写db.Save(&User{Name: "qaq"})会发生什么?发现多了一条新的记录也就是说按照主键找不到该内容的话,Save就会根据参数信息再创建一条新的信息。

Save这个方法只是一个单纯的保存行为,不能进行更多的操作了,因此按理来说只能通过上面一种方式来进行修改,不过参数u应该可以是个切片,只要信息里有主键就好了,举个例吧:

var u []User
db.Find(&u, "age = ?", 18)
u[0].Name = "firec"
u[1].Age = 7
db.Save(u)

总之只要你能把握好下标对应的到底是哪一条信息,这样做也无可厚非……

3.3.2 Update

与其他的方法不同的是,用Update之前要先用Model指定模型(到底在那张表上修改啊),如果我按照下面方法来操作:

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

这种情况下,很明显新创建的模型只告诉他这关于是users表修改,但是没有其他任何信息的,因此导致Update不知道到底要把谁的"age"修改为77,因此报错也是理所当然的事情了。(但是对于Model的描述中没有修改,实际上不可以通过这种方法直接全部修改。如果要全部修改还是要用Find)

那也就是说只要模型里有相关信息(最主要的是包含主键)就可以了:

var u User
db.First(&u)
db.Model(&u).Update("age", 77)

使用Where来进行条件修改也是可以的:

db.Model(&User{}).Where("age = 19").Update("name", "hello")

那他能不能同时修改好几个啊?试一试不就知道了:

var u []User
db.Find(&u, "age = ?", 18)
db.Model(&u).Update("age", 77)

结果是模型中所有的信息的"age"全被修改为77了,说明这是没有问题的!

话说为什么非要用一个Model而不是直接和其他的一样作为Update的参数捏?

3.3.3 Updates

这个就是同时修改多列的Update,可以用Map也可以用结构体,不多做说明了。

3.4 删

3.4.1 Delete

Delete还是先说条件删除吧,根据条件来删除问题就会少很多,其实和前面的一样:

db.Where("age = ?", 18).Delete(&User{})
db.Delete(&User{},"age = ?",18)

所以说到底是用u := new(User) db.Delete(u)还是db.Delete(&User{})完全取决于你是不是要用这个u(因为在函数内直接定义是匿名的,不能再次找到它了)。

显然在Delete中我都删了我还用什么……

那再讲非条件删除的Delete

db.Delete(&User{})
db.Delete(&User{Name: "fire"})

这样是无法运行的WHERE conditions required,因为之前的版本(我看的视频)用这种方法来进行Delete会导致整张表上的所有信息都被软删除,可能是为了防止这种事情发生就干脆禁止了。

唯一可行的方法是标记信息的主键:

u := new(User)
u.ID = 1
db.Delete(u)

只能通过这种方式来进行删除。

当然你说我非要把整张表删除了,他就是跟我有仇,那你可以先Find然后再Delete

u := new([]User) // 定义切片
db.Find(u)		// 查询所有,信息返回到u
db.Delete(u)	// 删除所有

只要是通过查询找出来要的u就是可以这么删除,当然不限于全删,也可以是条件删除。

4. 总结

  1. 添加行为,就是放进去一个实例,之后要用的话就不要用匿名。
  2. 查询行为,和上面差不多,但是大多数情况下不会用匿名来查询;并且查询行为是可以通过DB.Find(&User{})来进行整张表的查询的。
  3. 修改行为,是不可以全局修改的(即不存在DB.Model(&User{}).Update(...))这种操作的!因为修改就涉及到数据的准确性了。
  4. 删除行为,更是不能够直接全局修改了(DB.Delete(&User{})),否则很容易出事!

综上所述使用&User{}还是u := new(User)取决于之后会不会用到这个实例了;而没有信息的User实例(&User{}或者还没有赋值的u := new(User))所代表的是整个表(因为之前通过AutoMigrate绑定了表和结构体)。修改和删除都可以在查询的基础上进行。

标签:浅谈,db,tips05,修改,User,GO,First,Find,Delete
From: https://www.cnblogs.com/F0und/p/17208076.html

相关文章