目录
一、GORM
ORM:即Object-Relational Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了。
GORM:gorm是go语言的一个orm框架,Golang 写的,开发人员友好的 ORM 库。
安装GORM:
go get github.com/jinzhu/gorm
新建test_gorm项目
D:\GO_workspace_web>md test_gorm
D:\GO_workspace_web>cd test_gorm
D:\GO_workspace_web\test_gorm>go mod init test_gorm
go: creating new go.mod: module test_gorm
D:\GO_workspace_web\test_gorm>
使用GoLand打开项目,进入Terminal命令
PS D:\GO_workspace_web\test_gorm> go get github.com/jinzhu/gorm
go: downloading github.com/jinzhu/gorm v1.9.16
go: downloading github.com/jinzhu/inflection v1.0.0
go: added github.com/jinzhu/gorm v1.9.16
go: added github.com/jinzhu/inflection v1.0.0
PS D:\GO_workspace_web\test_gorm>
1、GORM连接数据库
package main
import (
_ "github.com/go-sql-driver/mysql" //引入mysql的驱动
"github.com/jinzhu/gorm"
)
func main() {
//连接数据库:
//Open传入两个参数:
//第一个参数:指定你要连接的数据库
//第二个参数:指的是数据库的设置信息:用户名:密码@tcp(ip:port)/数据库名字?charset=utf8&parseTime=True&loc=Local
//charset=utf8设置字符集
//parseTime=True为了处理time.Time
//loc=Local 时区设置,与本地时区保持一致
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
}
2、单表的增删改查
package main
import (
"fmt"
_ "github.com/go-sql-driver/mysql" //引入mysql的驱动
"github.com/jinzhu/gorm"
)
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.CreateTable(&User{}) //创建表,默认表名后加s
//db.Table("user").CreateTable(&User{}) //指定要创建的表名
//flg1 := db.HasTable(&User{}) //判断是否有某张表
//fmt.Println(flg1)
flg2 := db.HasTable("users") //判断是否有某张表
fmt.Println(flg2)
//db.DropTable(&User{}) //删除表
//db.DropTable("user") //指定删除表名
//增删改查
//增加
db.Create(&User{Name: "张无忌", Age: 30})
//查询
var muser User
db.First(&muser, "age=?", 30)
fmt.Println(muser)
//更新:先查询再更新
db.Model(&muser).Update("age", 40)
fmt.Println(muser)
db.Model(&muser).Update("name", "张翠山")
fmt.Println(muser)
//删除:先查询再删除
db.Delete(&muser)
fmt.Println(muser)
}
type User struct {
Name string
Age int
}
3、结构体名和表名的映射规则
- 如果结构体名没有驼峰命名,那么表名就是:结构体名小写+复数形式: 如结构体名User-->表名users
- 如果结构体名有驼峰命名,那么表名就是:大写变小写并在前面加下划线,最后加复数形式:如结构体名UserInfo-->表名user_infos
- 如有结构体名有连续的大写字母,那么表名就是:连续的大写字母变小写,驼峰前加下划线,字母变小写,最后加复数形式:如结构体名:DBUserInfo-->表名db_user_infos
- 结构体中字段名称与表中列名的映射规则同上
自定义表名
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
Age int
Name string
}
type UserInfo struct {
Age int
Name string
}
type DBUserInfo struct {
Age int
Name string
}
type MyUser struct {
Age int
Name string
}
func (MyUser) TableName() string {//自定义表名
return "test_my_user"
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.CreateTable(&User{})
db.CreateTable(&UserInfo{})
db.CreateTable(&DBUserInfo{})
db.CreateTable(&MyUser{})
}
4、gorm.Model匿名字段
只需要在自己的模型中指定gorm.Model匿名字段,即可在数据库表中包含四个字段:ID,CreatedAt,UpdatedAt,DeletedAt
ID:主键自增长
CreatedAt:用于存储记录的创建时间
UpdatedAt:用于存储记录的修改时间
DeletedAt:用于存储记录的删除时间
package main
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type MyTest struct {
gorm.Model
Age int
Name string
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.CreateTable(&MyTest{})
}
5、结构体标签gorm
通过结构体标签gorm来实现表的约束
gorm标签属性值:
(1)-: 忽略,不映射这个字段 eg: `gorm:"-"` ,适合:一些冗余字段,不想在数据库中体现,只想在结构体中体现
(2)primary_key:主键 eg: `gorm:"primary_key"`
PS:如果是想要加联合主键,在每个字段后加入 `gorm:"primary_key"`即可
例如:即可将StuID和Name作为联合主键
StuID int `gorm:"primary_key"`
Name string `gorm:"primary_key"`
(3)AUTO_INCREMENT:自增 eg: `gorm:"AUTO_INCREMENT"`
(4)not null:不为空,默认为空 eg: `gorm:"not null"`
(5)index:索引, eg: `gorm:"index"`
创建索引并命名:eg: `gorm:"index:idx_name_code"`
(6)unique_index:唯一索引 eg: `gorm:"unique_index"`
唯一性索引unique index和一般索引normal index最大的差异就是在索引列上增加了一层唯一约束。添加唯一性索引的数据列可以为空,但是只要存在数据值,就必须是唯一的。
(7)unique:唯一 eg: `gorm:"unique"`
(8)column:指定列名 eg: `gorm:"column:user_name"`
(9)size:字符串长度,默认为255 eg:`gorm:"size:10"`
(10)default `default:'男'` 默认值
(11)type:设置sql类型 eg: `gorm:"type:int(2)"`
PS:多个属性值之间用分号分隔
type Student struct {
StuID int `gorm:"primary_key;AUTO_INCREMENT"`
Name string `gorm:"not null"`
Age int `gorm:"unique_index"`
Email string `gorm:"unique"`
Sex string `gorm:"column:gender;size:10"`
Desc string `gorm:"-"`
Classno string `gorm:"type:int"`
}
6、多表操作
6.1、一对一关系
//1、
type User struct{
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
//关联关系
User User
//指定外键
UserId int
}
//2、通过gorm标签来指定外键:(属于关系:关系和外键的指定在同一方)
type User struct{
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
//关联关系
User User `gorm:"ForeignKey:MyUserID;AssociationForeignKey:UserId"`
//指定外键:
MyUserID int
}
//3、通过gorm标签来指定外键:(包含关系:关系和外键的指定不在同一方)
type User struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
IID int
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
User User `gorm:"ForeignKey:IID;AssociationForeignKey:InfoID"` //关联关系
}
操作:
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
IID int
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
User User `gorm:"ForeignKey:IID;AssociationForeignKey:InfoID"` //关联关系
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.DropTable(&User{})
db.DropTable(&UserInfo{})
db.CreateTable(&User{})
db.CreateTable(&UserInfo{})
fmt.Println("===========关联添加==============")
//关联添加数据: (因为关联关系在UserInfo表中,所以添加操作从UserInfo来入手)
userinfo := UserInfo{
Pic: "/upload/1.jpg",
Address: "北京海淀区",
Email: "124234@126.com",
User: User{
Age: 19,
Name: "丽丽",
},
}
db.Create(&userinfo)
fmt.Println("===========关联查询==============")
//关联查询:Association方式查询:Association方式查询缺点:先First查询,再Association查询
var userinfo1 UserInfo
//如果只是执行下面这步操作,那么关联的User信息是查询不到的:
db.First(&userinfo1, "info_id = ?", 1)
fmt.Println(userinfo1)
//如果想要查询到User相关内容,必须执行如下操作:
//Model参数:要查询的表数据,Association参数:关联到的具体的模型:模型名字User(字段名字)
//Find参数:查询的数据要放在什么字段中&userinfo.User
db.Model(&userinfo1).Association("User").Find(&userinfo1.User)
fmt.Println(userinfo1)
//关联查询:Preload方式查询:
var userinfo2 UserInfo
//查询info_id=1的数据放入userinfo中,并关联查询到User字段对应的数据
db.Preload("User").Find(&userinfo2, "info_id = ?", 1)
fmt.Println(userinfo2)
//关联查询:Related方式查询
var userinfo3 UserInfo
db.First(&userinfo3, "info_id = ?", 1)
fmt.Println(userinfo3)
var user User
//通过userinfo模型查出来的User字段的信息放入新的容器user中:
db.Model(&userinfo3).Related(&user, "User")
fmt.Println(user)
fmt.Println(userinfo3)
fmt.Println("===========关联更新==============")
//关联更新
//先查询
var userinfo11 UserInfo
db.Preload("User").Find(&userinfo11, "info_id = ?", 1)
fmt.Println(userinfo11)
//再更新:注意:Update的参数age可以用结构体中字段Age也可以用数据库age字段
db.Model(&userinfo11.User).Update("age", 31)
fmt.Println(userinfo11)
fmt.Println("===========关联删除==============")
//关联删除
//先查询
var userinfo12 UserInfo
db.Preload("User").Find(&userinfo12, "info_id = ?", 1)
fmt.Println(userinfo12)
//再删除:借助userinfo模型删除User记录
db.Delete(&userinfo12.User) //UserInfo中信息没有被删除,删除的是关联的User表中的记录
db.Delete(&userinfo12)
}
6.2、一对多关系
type Author struct {
AID int `gorm:"primary_key;AUTO_INCREMENT"`
Name string
Age int
Sex string
Article []Article `gorm:"ForeignKey:AuId;AssociationForeignKey:AID"`//关联关系
}
type Article struct {
ArId int `gorm:"primary_key;AUTO_INCREMENT"`
Title string
Content string
Desc string
AuId int//设置外键
}
操作:
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type Author struct {
AID int `gorm:"primary_key;AUTO_INCREMENT"`
Name string
Age int
Sex string
//关联关系:
Article []Article `gorm:"ForeignKey:AuId;AssociationForeignKey:AID"`
}
type Article struct {
ArId int `gorm:"primary_key;AUTO_INCREMENT"`
Title string
Content string
Desc string
//设置外键:
AuId int
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.DropTable(&Author{})
db.DropTable(&Article{})
db.CreateTable(&Author{})
db.CreateTable(&Article{})
fmt.Println("===========关联添加==============")
//关联添加数据:
author := Author{
Name: "张三",
Age: 30,
Sex: "男",
Article: []Article{
{
Title: "HTML入门",
Content: "HTML******",
Desc: "非常好",
},
{
Title: "CSS入门",
Content: "CSS******",
Desc: "此书不错",
},
},
}
db.Create(&author)
fmt.Println("===========关联查询==============")
//关联查询:Association方式查询:Association方式查询缺点:先First查询,再Association查询
var author1 Author
//如果只是执行下面这步操作,那么关联的User信息是查询不到的:
db.First(&author1, "a_id = ?", 1)
fmt.Println(author1)
//如果想要查询到Article相关内容,必须执行如下操作:
//Model参数:要查询的表数据,Association参数:关联到的具体的模型:模型名字Article(字段名字)
//Find参数:查询的数据要放在什么字段中&author.Article
db.Model(&author1).Association("Article").Find(&author1.Article)
fmt.Println(author1)
//关联查询:Preload方式查询:
var author2 Author
//查询a_id=1的数据放入author中,并关联查询到Article字段对应的数据
db.Preload("Article").Find(&author2, "a_id = ?", 1)
fmt.Println(author2)
//关联查询:Related方式查询
var author3 Author
db.First(&author3, "a_id = ?", 1)
fmt.Println(author3)
var as []Article
//通过author模型查出来的Article字段的信息放入新的容器as中:
db.Model(&author3).Related(&as, "Article")
fmt.Println(as)
fmt.Println(author3)
fmt.Println("===========关联更新==============")
//关联更新
//先查询
//Preload方式查询:
var author4 Author
//查询a_id=1的数据放入author中,并关联查询到Article字段对应的数据
db.Preload("Article").Find(&author4, "a_id = ?", 1)
fmt.Println(author4)
//再更新:
//如果直接Update操作那么关联的文章的记录就会被全部更改
//所以你要改动指定的记录必须加入限定条件:
db.Model(&author.Article).Where("ar_id = ?", 1).Update("title", "JS入门")
fmt.Println("===========关联删除==============")
//关联删除
//先查询
//Preload方式查询:
var author5 Author
//查询a_id=1的数据放入author中,并关联查询到Article字段对应的数据
db.Preload("Article").Find(&author5, "a_id = ?", 1)
fmt.Println(author5)
db.Where("ar_id = ?", 2).Delete(&author5.Article)
}
6.3、多对多关系
type Student struct {
SId int `gorm:"primary_key"`
SNo int
Name string
Sex string
Age int
Course []Course `gorm:"many2many:Student2Course"`//关联表
}
type Course struct {
CId int `gorm:"primary_key"`
CName string
TeacherName string
Room string
}
操作:
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type Student struct {
SId int `gorm:"primary_key"`
SNo int
Name string
Sex string
Age int
//关联表:
Course []Course `gorm:"many2many:Student2Course"`
}
type Course struct {
CId int `gorm:"primary_key"`
CName string
TeacherName string
Room string
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.DropTable(&Student{})
db.DropTable(&Course{})
db.CreateTable(&Student{})
db.CreateTable(&Course{})
fmt.Println("===========关联添加==============")
//关联添加数据:
stu := Student{
SNo: 1001,
Name: "丽丽",
Sex: "女",
Age: 18,
Course: []Course{
{
CName: "c++",
TeacherName: "张三",
Room: "s-103",
},
{
CName: "高数",
TeacherName: "李四",
Room: "s-801",
},
},
}
db.Create(&stu)
fmt.Println("===========关联查询==============")
//关联查询:Association方式查询:Association方式查询缺点:先First查询,再Association查询
var student Student
//如果只是执行下面这步操作,那么关联的User信息是查询不到的:
db.First(&student, "s_id = ?", 1)
fmt.Println(student)
//如果想要查询到Article相关内容,必须执行如下操作:
//Model参数:要查询的表数据,Association参数:关联到的具体的模型:模型名字Article(字段名字)
//Find参数:查询的数据要放在什么字段中&student.Course
db.Model(&student).Association("Course").Find(&student.Course)
fmt.Println(student)
//关联查询:Preload方式查询:
var student1 Student
db.Preload("Course").Find(&student1, "s_id = ?", 1)
fmt.Println(student1)
//关联查询:Related方式查询
var student2 Student
db.First(&student2, "s_id = ?", 1)
fmt.Println(student2)
var course []Course
//通过author模型查出来的Article字段的信息放入新的容器as中:
db.Model(&student2).Related(&course, "Course")
fmt.Println(course)
fmt.Println(student2)
fmt.Println("===========关联更新==============")
//关联更新
//先查询
//Preload方式查询:
var student3 Student
db.Preload("Course").Find(&student3, "s_id = ?", 1)
fmt.Println(student3)
//再更新:
//如果直接Update操作那么关联的文章的记录就会被全部更改
//所以你要改动指定的记录必须加入限定条件:
db.Model(&student3.Course).Where("c_id = ?", 1).Update("c_name", "Java")
fmt.Println("===========关联删除==============")
//关联删除
//先查询
//Preload方式查询:
var student4 Student
db.Preload("Course").Find(&student4, "s_id = ?", 1)
fmt.Println(student4)
db.Where("c_id = ?", 2).Delete(&student4.Course)
}
7、常用方法
【1】First:按照条件查询,并且升序排列,查询出一条记录
【2】FirstOrCreate:有数据就查询出来,没有就创建一条记录
【3】Last:按照条件查询,并且降序排列,查询出一条记录
【4】Take:按照条件查询,查询出一条记录
【5】Find:按照条件查询
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
IID int
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
//增加:Exec
db.Exec("insert into users (age,name) values (?,?)", 18, "张无忌")
//First:
var user User
db.Debug().First(&user, 1) //-->默认情况查询的是主键
fmt.Println(user)
db.Debug().First(&user, "user_id = ?", 1)
fmt.Println(user)
db.Debug().Where("user_id = ?", 1).First(&user)
fmt.Println(user)
//FirstOrCreate:SELECT * FROM `users` WHERE `users`.`user_id` = 1 AND ((user_id = 1)) ORDER BY `users`.`user_id` ASC LIMIT 1
user2 := User{ //这里定义的结构体的实例的数值其实就是FirstOrCreate的查询条件
UserId: 2,
Age: 20,
Name: "菲菲",
IID: 1,
}
//如果有对应的数据,就查询出来,如果没有对应的数据,就会帮我们创建新的记录
db.FirstOrCreate(&user, user2)
fmt.Println(user)
//Last:SELECT * FROM `users` WHERE `users`.`user_id` = 2 AND ((`users`.`user_id` = 1)) ORDER BY `users`.`user_id` DESC LIMIT 1
db.Debug().Last(&user, 1)
fmt.Println(user)
//Take:SELECT * FROM `users` WHERE `users`.`user_id` = 2 AND ((`users`.`user_id` = 1)) LIMIT 1
db.Debug().Take(&user, 1)
fmt.Println(user)
//Find:SELECT * FROM `users` WHERE `users`.`user_id` = 2 AND ((`users`.`user_id` IN (1,2)))
user_id_arr := []int{1, 2}
db.Debug().Find(&user, user_id_arr)
fmt.Println(user)
}
【6】Where:加入指定条件:
具体条件为:=,like,in,and,between....
【7】Select:筛选查询出来的字段
【8】Create:添加数据
【9】Save:添加数据
【10】Update:更新数据
【11】Delete:删除数据
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
IID int
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
//增加:Exec
db.Exec("insert into users (age,name) values (?,?)", 18, "张无忌")
//Where
var user User
db.Debug().Where("user_id = ?", 1).First(&user)
fmt.Println(user)
db.Debug().Where("user_id in (?)", []int{1, 2}).First(&user)
fmt.Println(user)
//Select
db.Debug().Select("name,age").Where("user_id = ?", 1).First(&user)
fmt.Println(user)
//Create:操作只可以插入一条技能,不能批量操作
user2 := User{
Age: 26,
Name: "小明",
IID: 1,
}
db.Create(&user2)
//Save
user3 := User{
Age: 14,
Name: "莎莎",
IID: 1,
}
db.Save(&user3)
//Update更新:先查询再更新:
var user4 User
//(1)先查询,再通过Model进行操作,再Update操作:
db.Where("user_id = ?", 1).First(&user4)
db.Model(&user4).Update("age", 29)
fmt.Println(user4)
//(2)直接在查询之后进行操作:
db.Where("user_id = ?", 1).First(&user4).Update("name", "露露")
fmt.Println(user4)
//(3)直接在查询之后进行操作,传入结构体示例,更新多个字段
db.Where("user_id = ?", 1).First(&user4).Update(User{
Age: 11,
Name: "小刚",
})
fmt.Println(user4)
//(4)直接在查询之后进行操作,传入map,更新多个字段
db.Where("user_id = ?", 1).First(&user4).Update(map[string]interface{}{
"age": 21,
"name": "小花",
})
fmt.Println(user4)
//Delete:删除数据:
// (1)先查询再删除:
var user5 User
db.Where("user_id = ?", 1).First(&user5)
db.Delete(&user5)
//(2)通过条件直接进行删除:
var user6 User
db.Where("user_id = ?", 2).Delete(&user6)
}
【12】Not:排除某个具体条件的查询操作
【13】Or:多个条件的查询
【14】Order:进行升序或者降序的排列
【15】Limit:指定获取记录的最大数量
【16】Offset:设置偏移
【17】Scan:将结果扫描到另一个结构体中
【18】Count:计数
【19】GROUP:进行分组
【20】Having:分组后进行过滤
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
IID int
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
db.DropTable(&User{})
db.CreateTable(&User{})
//增加:Exec
db.Exec("insert into users (age,name) values (?,?)", 28, "张无忌")
db.Exec("insert into users (age,name) values (?,?)", 26, "赵敏")
db.Exec("insert into users (age,name) values (?,?)", 25, "小昭")
//Not:
var users []User
db.Not("user_id = ?", 1).Find(&users)
fmt.Println(users)
var users1 []User
db.Debug().Not(User{
Age: 18,
Name: "丽丽",
}).Find(&users1)
fmt.Println(users1)
//Or :
var users2 []User
db.Where("user_id = ?", 1).Or("user_id = ?", 3).Find(&users2)
fmt.Println(users2)
//Order:
var users3 []User
db.Where("age = ?", 26).Order("user_id asc").Find(&users3)
fmt.Println(users3)
//Limit:
var users4 []User
db.Limit(2).Find(&users4)
fmt.Println(users4)
//Offset:
//注意:Offset中设置的偏移数字为第几条记录,从0开始,0、1、2、、、、
//注意:Offset必须和Limit结合使用
var users5 []User
db.Offset(1).Limit(2).Find(&users5)
fmt.Println(users5)
//Scan
type UserDemo struct { //你要扫描的结构体的字段的名字和User中的字段名字必须一致才可以扫描
Name string
Age int
}
var userdemo UserDemo
var user User
db.Where("user_id=?", 1).Find(&user).Scan(&userdemo)
fmt.Println(user)
fmt.Println(userdemo)
//Count:
var users6 []User
//定义一个变量接收计数的数量:
var count int
db.Find(&users6).Count(&count)
fmt.Println(users6)
fmt.Println(count)
//Group:
var users7 []User
//定义一个新的结构体:
type GroupData struct {
Age int
Count int
}
var group_date []GroupData
//Having:在分组以后进行过滤
db.Debug().Select("age,count(*) as count").Group("age").Find(&users7).Having("age > 18").Scan(&group_date)
fmt.Println(users7)
fmt.Println(group_date)
}
【21】Join :左连接、右连接:
【22】LogMod:
Gorm内置的日志记录器,显示详细日志
PS :利用Debug只能逐条打印对应日志信息,但是设置LogMod(true)相当于设置了全局打印,所有执行的逻辑日志都会帮我们输出打印
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
UserId int `gorm:"primary_key;AUTO_INCREMENT"`
Age int
Name string
IID int
}
type UserInfo struct {
InfoID int `gorm:"primary_key;AUTO_INCREMENT"`
Pic string
Address string
Email string
User User `gorm:"ForeignKey:IID;AssociationForeignKey:InfoID"` //关联关系
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
//开启打印日志:
db.LogMode(true)
db.DropTable(&User{})
db.DropTable(&UserInfo{})
db.CreateTable(&User{})
db.CreateTable(&UserInfo{})
//增加:Exec
db.Exec("insert into users (age,name) values (?,?)", 28, "张无忌")
db.Exec("insert into users (age,name) values (?,?)", 26, "赵敏")
db.Exec("insert into users (age,name) values (?,?)", 25, "小昭")
//Joins:
//定义一个新的结构体用于Scan:
type NewUserInfo struct {
User_Id int
Name string
I_Id int
Info_Id int
Address string
}
var newUser []NewUserInfo
var users []User
db.Select("users.user_id,users.name,users.i_id,user_infos.info_id,user_infos.address").Joins("left join user_infos on users.i_id = user_infos.info_id").Find(&users).Scan(&newUser)
fmt.Println(users)
fmt.Println(newUser)
}
8、支持原生SQL
package main
import (
"fmt"
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
type User struct {
Name string
Age int
}
func main() {
db, err := gorm.Open("mysql", "root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if err != nil {
panic(err)
}
defer db.Close()
//开启打印日志:
db.LogMode(true)
db.CreateTable(&User{})
//增加:Exec
db.Exec("insert into users (age,name) values (?,?)", 18, "张无忌")
//查询操作:Raw
var users []User
db.Raw("select * from users where age = ?", 18).Find(&users)
fmt.Println(users)
//删除、修改:Exec
db.Exec("update users set name = ? where age = ?", "明明", 18)
db.Exec("delete from users where age = ?", 18)
}
运行结果
(D:/GO_workspace_web/test_gorm/part04/main.go:23)
[2023-08-19 21:48:51] [40.40ms] CREATE TABLE `users` (`name` varchar(255),`age` int )
[0 rows affected or returned ]
(D:/GO_workspace_web/test_gorm/part04/main.go:26)
[2023-08-19 21:48:51] [5.56ms] insert into users (age,name) values (18,'张无忌')
[1 rows affected or returned ]
(D:/GO_workspace_web/test_gorm/part04/main.go:29)
[2023-08-19 21:48:51] [0.63ms] select * from users where age = 18
[1 rows affected or returned ]
[{张无忌 18}]
(D:/GO_workspace_web/test_gorm/part04/main.go:32)
[2023-08-19 21:48:51] [4.09ms] update users set name = '明明' where age = 18
[1 rows affected or returned ]
(D:/GO_workspace_web/test_gorm/part04/main.go:33)
[2023-08-19 21:48:51] [10.08ms] delete from users where age = 18
[1 rows affected or returned ]
Process finished with the exit code 0
9、Gin整合GORM
DB操作提取
package dbope
import (
"github.com/jinzhu/gorm"
_ "github.com/jinzhu/gorm/dialects/mysql"
)
var Db *gorm.DB
var Err error
func init() {
Db,Err = gorm.Open("mysql","root:root@tcp(localhost:3306)/testgorm?charset=utf8&parseTime=True&loc=Local")
if Err != nil {
panic(Err)
}
}
main.go
package main
import (
"test_gorm/part12/dbope"
"github.com/gin-gonic/gin"
)
type Student struct {
Id int `gorm:"primary_key"`
Name string
Age int
}
func AddStu(context *gin.Context) {
stu := Student{
Name: "露露",
Age: 21,
}
dbope.Db.DropTable(&stu)
dbope.Db.CreateTable(&stu)
//添加操作
dbope.Db.Create(&stu)
//关闭资源:
dbope.Db.Close()
}
func main() {
r := gin.Default()
r.GET("/addStu", AddStu)
r.Run()
}
人必须要成长!
如今一道为尊,万道相和,几乎很难破。最可怕的是苍穹!