gorm基本操作

一、gorm安装

1.下载gorm

go 复制代码
go get -u gorm.io/gorm //gorm框架
go get -u gorm.io/driver/mysql //驱动

2.mysql准备工作

go 复制代码
mysql> create database godb;
mysql> grant all on *.* to 'admin'@'%' identified by 'golang123!';
mysql> flush privileges;

3.导入gorm框架

go 复制代码
import (
	"gorm.io/gorm"
	"gorm.io/driver/mysql"
)

4.连接mysql

这里单独创建一个连接mysql的包,

go 复制代码
package mysqldb

import (
	"gorm.io/driver/mysql"
	"gorm.io/gorm"
)

func Mysql_connect() *gorm.DB {

	dsn := "admin:golang123!@tcp(192.168.1.23:3306)/godb?charset=utf8mb4&parseTime=True&loc=Local"
	db, _ := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	return db
}

5.引入连接包函数

go 复制代码
package main

import (
	"fmt"
	"gorm/mysqldb"
)

func main() {
	db := mysqldb.Mysql_connect()
	fmt.Println(db)
}

此时如果没有报错,说明连接mysql已经成功了

二、基本使用

1.创建和表对应的结构体

这里新建了一个db.go 也属于mysqldb包

go 复制代码
package mysqldb

import "time"

//共用结构体,其它结构体直接继承即可,字段是所有表共用字段,所有做一个基础结构体,减少重复定义。
//反撇号中的内容是"标签"。标签的含义结构体转换成另外一种格式的时候,传递过去一些信息
//其实在gorm中有一个自带的gorm.Model结构体,和这里自建的BaseModule 基本一致
type BaseModule struct {
	Id         int        `gorm:"primarykey"`
	CreateTime *time.Time `gorm:"autoCreateTime"`
	UpdateTime *time.Time `gorm:"autoCreateTime"`
}

//创建老师表
type Teacher struct {
	BaseModule        //继承共用结构体,这里使用了匿名字段,使用数据类型(结构体类型)作为字段名称
    Name       string        `gorm:"type:varchar(32);unique;not null"`
	Tno        int    //账号
	Pwd        string //密码
	Tel        string //电话
}

2.teacher表

在main.go中开始初始Teacher表

go 复制代码
package main

import (
	"gorm/mysqldb"
)

func main() {
	db := mysqldb.Mysql_connect()
    //开始初始化表
	db.AutoMigrate(&mysqldb.Teacher{})
}

查看数据库内容teachers表已经创建好。这里可以看到 BaseModel 不用初始化为数据库表。teacher表中也会继承了它的字段

mysql 复制代码
mysql> use godb
Database changed
mysql> show tables;
+----------------+
| Tables_in_godb |
+----------------+
| teachers       |
+----------------+
1 row in set (0.00 sec)

mysql> desc teachers;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| create_time | datetime(3) | YES  |     | NULL    |                |
| update_time | datetime(3) | YES  |     | NULL    |                |
| name        | varchar(32) | NO   | UNI | NULL    |                |
| tno         | bigint(20)  | YES  |     | NULL    |                |
| pwd         | longtext    | YES  |     | NULL    |                |
| tel         | longtext    | YES  |     | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
7 rows in set (0.00 sec)

2.1 手动插入数据

这里手动插入数据。ID列是自增长列,在手动插入数据的时候写NULL就可以了。两个时间字段用now()函数就可以了

sql 复制代码
mysql>insert into  teachers values(NULL,now(),now(),"teacher wang",3123,"wang!","13312312311");
mysql> select * from teachers;
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
| id | create_time             | update_time             | name         | tno  | pwd   | tel         |
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
|  1 | 2023-07-20 22:37:20.000 | 2023-07-20 22:37:20.000 | teacher wang | 3123 | wang! | 13312312311 |
+----+-------------------------+-------------------------+--------------+------+-------+-------------+
1 row in set (0.00 sec)

2.2 在次初始化

cmd 复制代码
go run main.go

此时发现数据没有受到任何影响。

但是会重复生成: UNIQUE KEY. 通过show create table 表名查看

2.3 表名变复数

结构体的名称为teacher 但是创建的表变成了teachers 多了一个s 这是在迁移过程中库自己加的。如果不影响使用可以忽略。

3.class表

class表对应结构体如下

go 复制代码
type Class struct {
	BaseModule
	Name string `gorm:"type:varchar(32);unique;not null"`
	Num  int
	TId  int
	T    Teacher
}

注意:

powershell 复制代码
TId  int 
这个字段是外键字段,字段的值指向 teacher表的 id 字段值
powershell 复制代码
T    Teacher
这个成员变量不会在mysql中产生字段。这是设置的 TId字段的 外键关联语句,相当于 foreign key 字段名 refences 主表(id)

1.T的意思是:gorm会根据这个名字(T)自动在后边加上Id,然后在结构体中找这个变量,并且将这个字段设置为外键。 也就是说 T = TId. 如果你的外键字段在命名时,那将设置外键关联失败
2.Teacher的意思是: 它是Teacher表, gorm在管理的时候 会自动关联到Teacher的ID字段

这中简写方式是gorm 提供的语法糖

1.开始迁移

go 复制代码
package main

import (
	"gorm/mysqldb"
)

func main() {
	db := mysqldb.Mysql_connect()
	db.AutoMigrate(&mysqldb.Class{})

}

2.查看表

mysql 复制代码
mysql> show tables;
+----------------+
| Tables_in_godb |
+----------------+
| classes        |
| teachers       |
+----------------+
2 rows in set (0.00 sec)

mysql> desc classes;
+-------------+-------------+------+-----+---------+----------------+
| Field       | Type        | Null | Key | Default | Extra          |
+-------------+-------------+------+-----+---------+----------------+
| id          | bigint(20)  | NO   | PRI | NULL    | auto_increment |
| create_time | datetime(3) | YES  |     | NULL    |                |
| update_time | datetime(3) | YES  |     | NULL    |                |
| name        | varchar(32) | NO   | UNI | NULL    |                |
| num         | bigint(20)  | YES  |     | NULL    |                |
| t_id        | bigint(20)  | YES  | MUL | NULL    |                |
+-------------+-------------+------+-----+---------+----------------+
6 rows in set (0.00 sec)


mysql> show create table classes;

| classes | CREATE TABLE `classes` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `create_time` datetime(3) DEFAULT NULL,
  `update_time` datetime(3) DEFAULT NULL,
  `name` varchar(32) NOT NULL,
  `num` bigint(20) DEFAULT NULL,
  `t_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `name` (`name`),
  KEY `fk_classes_t` (`t_id`),
  //这里已经创建好了外键关联
  CONSTRAINT `fk_classes_t` FOREIGN KEY (`t_id`) REFERENCES `teachers` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |

三、新增数据

1.Teacher表新增数据

go 复制代码
package main

import (
	"gorm/mysqldb"

	"gorm.io/gorm"
)

func Insert(db *gorm.DB) {
	t1 := mysqldb.Teacher{Name: "wang", Tno: 1, Pwd: "123!", Tel: "11012341235"}
	db.Create(&t1)
}

func main() {
	db := mysqldb.Mysql_connect()
	Insert(db)

}

1.1.注意事项1

go 复制代码
t1 := mysqldb.Teacher{Name: "wang", Tno: 1, Pwd: "123!", Tel: "11012341235"}
实例化的时候使用键值对的方式赋值,不要使用{"wang",1,"123!","11012341235"}这种方式,因为我们继承了BaseModule

1.2.注意事项2

go 复制代码
db.Create(&t1)
在新增数据的时候,一定要传入结构体实例的指针,因为gorm要把主键值回写到结构体实例

1.3 新增结果

这里可以看到,在新增的的时候,没有新增BaseModule的数据,但是在数据里自动生成了。并且ID是自增长的

sql 复制代码
mysql> select * from teachers;
+----+-------------------------+-------------------------+------+------+------+-------------+
| id | create_time             | update_time             | name | tno  | pwd  | tel         |
+----+-------------------------+-------------------------+------+------+------+-------------+
|  1 | 2023-08-03 10:21:03.551 | 2023-08-03 10:21:03.551 | wang |    1 | 123! | 11012341235 |
+----+-------------------------+-------------------------+------+------+------+-------------+
1 row in set (0.00 sec)

2.Class新增数据

go 复制代码
func InsertClass(db *gorm.DB) {
	c1 := mysqldb.Class{Name: "python", Num: 30, TId: 1}
	db.Create(&c1)

}

插入数据如下:

sql 复制代码
mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
1 row in set (0.00 sec)

2.1 插入多条数据

go 复制代码
func InsertClass(db *gorm.DB) {
	c2 := mysqldb.Class{Name: "java", Num: 30, TId: 1}
	c3 := mysqldb.Class{Name: "go", Num: 30, TId: 1}
	c4 := mysqldb.Class{Name: "shell", Num: 30, TId: 1}

	class_list := []mysqldb.Class{c2, c3, c4}
	db.Create(&class_list)

}

插入数据如下:

sql 复制代码
mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | go     |   30 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+

四、单表查询

1.查询全部 db.Find()

go 复制代码
func selectdata(db *gorm.DB) {
	// 这里定义切片的含义:
	// 1. 因为返回是多条数据,所以定义Class类型切片
	// 2. db.find函数是根据这里result的类型来判定去库里查找对应的哪张表
	var result []mysqldb.Class

	// 将查询结果集回写到result切片当中
	db.Find(&result)


	for i, v := range result {
		fmt.Println("i = ", i)
		fmt.Println("v = ", v.Name)

	}
}

执行结果如下:

go 复制代码
E:\code\project\后端项目\go_project\gin框架学习>go run main.go
i =  0
v =  python
i =  1
v =  java
i =  2
v =  go
i =  3
v =  shell

2.查询单条

go 复制代码
func selectdata(db *gorm.DB) {
    //三个变量设置的都是结构体实例,不是切片,因为查询结果是一条。
	var result mysqldb.Class
	var result1 mysqldb.Class
	var result2 mysqldb.Class

	db.Take(&result)     //获取第一条记录,没有指定排序字段
	db.First(&result1)  //获取第一条记录(主键升序)
	db.Last(&result2)   //获取最后一条记录,主键降序

	fmt.Println("result = ", result)
	fmt.Println("result1 = ", result1)
	fmt.Println("result2 = ", result2)

}

3.where查询

注意: where条件查询的时候,条件参数不能直接写,必须使用? 然后在将参数传递给?

3.1.等值查询

go 复制代码
func selectdata(db *gorm.DB) {
	var result []mysqldb.Class
	db.Where("Name = ?", "java").Find(&result)
	fmt.Println("result = ", result)
}

3.2 大于查询

go 复制代码
func selectdata(db *gorm.DB) {
	var result []mysqldb.Class
	db.Where("update_time > ?", "2023-08-08 13:40:00").Find(&result)
	fmt.Println("result = ", result)
}

3.3 and

go 复制代码
func selectdata(db *gorm.DB) {
	var result []mysqldb.Class
	db.Where("num = ? and name = ?", 30, "go").Find(&result)
	fmt.Println("result = ", result)
}

4. db.select

查询结果返回部分字段,而不是全部字段.

go 复制代码
func selectdata(db *gorm.DB) {
	var result []mysqldb.Class
	db.Select("Name,num").Where("num = ? and name = ?", 30, "go").Find(&result)
	fmt.Println("result = ", result)
}

这里只返回了Name和Num两个字段,其他字段内容没有进行回写

5.db.Omit

除了Name和Num字段 其他的字段其全部返回

go 复制代码
func selectdata(db *gorm.DB) {
	var result []mysqldb.Class
	db.Omit("Name,Num").Where("num = ? and name = ?", 30, "go").Find(&result)
	fmt.Println("result = ", result)
}

五、更新

数据库数据如下:

sql 复制代码
mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | go     |   30 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+

1.修改单个字段

将go 改为golang

这里的db.Model 是用来指定表对应的结构体。

复制代码
func update_data(db *gorm.DB) {
	db.Model(&mysqldb.Class{}).Where("id = ?", 3).Update("name", "golang")
}

修改成功

sql 复制代码
mysql> select * from classes where id = 3;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | golang |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
1 row in set (0.00 sec)

2.修改多个字段

注意这里用的是updates,上边用的是update

go 复制代码
func update_data(db *gorm.DB) {
	db.Model(&mysqldb.Class{}).Where("id = ?", 3).Updates(mysqldb.Class{Name: "c++", Num: 20})

}

修改成功

sql 复制代码
mysql> select * from classes where id = 3;
+----+-------------------------+-------------------------+------+------+------+
| id | create_time             | update_time             | name | num  | t_id |
+----+-------------------------+-------------------------+------+------+------+
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | c++  |   20 |    1 |
+----+-------------------------+-------------------------+------+------+------+
1 row in set (0.00 sec)

3.更新表达式gorm.Expr

go 复制代码
func update_data(db *gorm.DB) {
	db.Model(&mysqldb.Class{}).Where("id = ?", 3).Update("num", gorm.Expr("num + 1"))

}

更改结果如下:

sql 复制代码
mysql> select * from classes;
+----+-------------------------+-------------------------+--------+------+------+
| id | create_time             | update_time             | name   | num  | t_id |
+----+-------------------------+-------------------------+--------+------+------+
|  1 | 2023-08-08 13:35:01.489 | 2023-08-08 13:35:01.489 | python |   30 |    1 |
|  2 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | java   |   30 |    1 |
|  3 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | c++    |   21 |    1 |
|  4 | 2023-08-08 14:14:15.927 | 2023-08-08 14:14:15.927 | shell  |   30 |    1 |
+----+-------------------------+-------------------------+--------+------+------+
4 rows in set (0.00 sec)
相关推荐
花酒锄作田5 天前
Gin 框架中的规范响应格式设计与实现
golang·gin
风流 少年5 天前
mysql mcp
数据库·mysql·adb
轩情吖6 天前
MySQL初识
android·数据库·sql·mysql·adb·存储引擎
qwfys2006 天前
How to install golang 1.26.0 to Ubuntu 24.04
ubuntu·golang·install
codeejun6 天前
每日一Go-25、Go语言进阶:深入并发模式1
开发语言·后端·golang
石牌桥网管6 天前
Go 泛型(Generics)
服务器·开发语言·golang
小二·6 天前
Go 语言系统编程与云原生开发实战(第21篇)
开发语言·云原生·golang
小二·6 天前
Go 语言系统编程与云原生开发实战(第20篇)
开发语言·云原生·golang
女王大人万岁6 天前
Golang实战Eclipse Paho MQTT库:MQTT通信全解析
服务器·开发语言·后端·golang
codeejun6 天前
每日一Go-24、Go语言实战-综合项目:规划与搭建
开发语言·后端·golang