Go framework-GORM

目录

一、GORM

1、GORM连接数据库

2、单表的增删改查

3、结构体名和表名的映射规则

4、gorm.Model匿名字段

5、结构体标签gorm

6、多表操作

7、常用方法

8、支持原生SQL

9、Gin整合GORM


一、GORM

        ORM:即Object-Relational Mapping,它的作用是在关系型数据库和对象之间作一个映射,这样,我们在具体的操作数据库的时候,就不需要再去和复杂的SQL语句打交道,只要像平时操作对象一样操作它就可以了。

        GORM:gorm是go语言的一个orm框架,Golang 写的,开发人员友好的 ORM 库。

GORM官网网站

GORM github源码

安装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、结构体名和表名的映射规则

  1. 如果结构体名没有驼峰命名,那么表名就是:结构体名小写+复数形式: 如结构体名User-->表名users
  2. 如果结构体名有驼峰命名,那么表名就是:大写变小写并在前面加下划线,最后加复数形式:如结构体名UserInfo-->表名user_infos
  3. 如有结构体名有连续的大写字母,那么表名就是:连续的大写字母变小写,驼峰前加下划线,字母变小写,最后加复数形式:如结构体名:DBUserInfo-->表名db_user_infos
  4. 结构体中字段名称与表中列名的映射规则同上

自定义表名

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()
}

Web framework-Gin

Golang学习+深入(一)

人必须要成长!

如今一道为尊,万道相和,几乎很难破。最可怕的是苍穹!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

杀神lwz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值