请先阅读官方文档,由于官方文档对每个例子和概念解释比较简单,官方文档中个人认为比较难理解的概念在正文章节进行解释
本文须与官方文档伴食,否则将不知所云。
可对应 学习项目 实践验证。
gorm.DB的方法定义采用了构造模式(所以才能连调多个方法),一个把较多方法用上的查询语句如下:
//伪代码,仅作方法简单罗列参考,且其中某些函数没有场景可以同时使用,顺序也没有严格思考。
db.Table(xxx).Select(xxx).Where(xxx).Or(xxx)Order(xxx).Limit(xxx).Offset(xxx).Attrs(xxx).FirstOrInit(&user).Count(xxx)
以下方法根据方法名语义查询(PS:个人称其为语义查询),涉及排序都是以主键排序
First/Take/Last/Find/
调用Where
方法进行条件查询
带占位符的SQL语句+与占位符对应个数的参数;
用Struct或Map携带条件(条件关系为And)或用切片携带主键(多个主键关系为Or)
调用语义查询方法
结构体查询注意零值问题
与Where类似,语义相反,条件格式也类似Where
个人认为完全可以使用Where的In条件代替,如下:
// IN
db.Where("name IN (?)", []string{"jinzhu", "jinzhu 2"}).Find(&users)
//// SELECT * FROM users WHERE name in (‘jinzhu‘,‘jinzhu 2‘);
实际就是在语义查询方法内直接放查询条件(省略Where语句),条件格式包括:
通过gorm:query_option
Tag格式指定查询行为
逻辑稍微复杂的语义查询方法,可选择性配合(可以不用)Attrs或Assign辅助方法。
虽然叫高级查询,也确实逻辑较复杂,但是部分方法完全属于高级DML的方法式使用。与前文的简单DML方法式使用涉及较多参数格式和gorm抽象出来的易用方法不同,只要理解对用的高级DML就能理解这些方法的使用。所以对这部分方法不做过多解释。
// Model specify the model you would like to run db operations
// // update all users‘s name to `hello`
// db.Model(&User{}).Update("name", "hello")
// // if user‘s primary key is non-blank, will use it as condition, then will only update the user‘s name to `hello`
// db.Model(&user).Update("name", "hello")
func (s *DB) Model(value interface{}) *DB {
c := s.clone()
c.Value = value
return c
}
个人理解:作用与db.Table(xxx)
相同,Table是通过数据库表名来指定要查询的表,Model是通过要查询的Struct的变量指针来指定要查询的表。
对查询结果某字段取切片,相当于更简洁2、更省内存的 Select(一个字段)
;因为Select方式结果是对应的自定义Type切片,而Pluck方式结果是对应字段的Buildin Type切片,但二者有效内容一样。
对应面向对象思想,Find系列方法相当于直接查出PO,Scan相当于查出另外定义的VO;Scan查询的是PO的部分字段。
gorm.DB的方法定义采用了构造模式(所以才能连调多个方法),一个把较多方法用上的更新语句如下:
db.Save(&user)
db.Model(&user).[Select(xxx)|Omit(xxx)].Where(xxx).Updates(xxx)
Save(&user)
更新id为&user.ID的记录的所有字段。Update(xxx)
配合Model或Table更新指定表的指定字段,xxx可以是键值对/Map/Struct变量
db.Delete(&email)
,如果没指定主键删除该Model所有记录DeletedAt
字段原文:https://www.cnblogs.com/wangbs95/p/13859641.html