这是关于gorm的数据查询的一篇笔记,主要介绍了使用gorm编写查询单个对象的语句的方法
首先是搭建测试环境,我使用的是gorm2和mysql数据库,使用命令go get -u gorm.io/gorm 和go get -u gorm.io/driver/mysql 导入项目依赖。然后连接数据库
dsn := "root:root123456@tcp(192.168.157.129:3306)/tiktok_go?charset=utf8mb4&parseTime=True"
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
查询操作对比
接下来就是查询操作的简单介绍了。先展示一下我用于测试的数据库表
我写了一个代码块,测试使用gorm的不同库函数进行查询效果之间的差异。之后的输出结果都是在替换了查询语句部分的代码后得到的不同结果。
user := User{}
res := _______查询语句________
fmt.Printf("%#v \n", user) //打印查询到的用户信息
//如果没有找到,输出内容
if errors.Is(res.Error, gorm.ErrRecordNotFound) {
fmt.Print("未找到该用户")
}
此处需要注意的是gorm.ErrRecordNotFound是由gorm提供的,用于表示查找不到符合条件的数据的错误。我们可以将查询操作的返回值中的Error字段内容取出与其对比,就能够判断我们是否找到符合条件的数据了。
使用db.Raw("select * from users where id = ?", 1).Take(&user)"语句查询
输出结果如下:
查询的是不存在的数据,所以res.Error可以取得错误为gorm.ErrRecordNotFound。(如果将条件中id = 1 改为4或5或6这种表里有的那就是对的,不会报错而且可以找出数据)
然后我们来介绍一下这个语句中使用的方法,Raw方法是gorm提供的用于调用原生sql语句的方法,使用Raw方法来书写查询语句的优势显而易见,我们使用的sql语句是相当直观的,只要看一眼字符串中的内容就知道这个sql语句是要做什么。但是缺点就是容易出错,比如写错字段名)。Take()方法用于获取一条数据,接收数据时向Take传入实例的指针,让Take方法将数据存储到实例中,这与c/c++的指针传递类似。
然后我们使用db.Raw("select * from users where id = ?", 1).Scan(&user)试试。
输出结果如下:
与上一个方法不同的是此处使用了Scan()替换了Take(),虽然我们查询的数据仍然不存在,但是此时控制台不再输出错误信息了。所以当我们不是很需要关注数据是否存在时,可以使用Scan()方法(此时用debug工具会发现res.Error的值为nil)
如果不想使用原生的sql语句呢,我们可以使用gorm提供的Where(),Or(),Not()等方法来拼接sql语句,比如我们可以使用这样的语句
res := db.Where("id = ?", 1).Or("username = ?", "aaaaaa").Take(&user)
输出结果如下:
我们从数据库中查询到了信息,此处相当于调用了sql语句
SELECT * FROM `users` WHERE (id = 1 OR username = 'aaa') AND `users`.`deleted_at` IS NULL LIMIT 1
显然 where中的条件被or连接起来了,这样就实现了或的逻辑。
补充: delete_at是由gorm支持的逻辑删除字段DeleteAt,具体可以参考gorm官方文档,limit 1是因为使用了Take()方法,限制了查询数据条数为1