gorm实现CRUD| 青训营

108 阅读5分钟

GORM

GORM官网

gorm是go语言中一个重要的orm库,用来连接和操作数据库

项目结构

│─ docker-compose.yaml
│─ go.mod
│─ main.go
└─config
    └─sql
        └─ init.sql

安装

在项目根目录下运行

go get -u gorm.io/gorm

数据库

要连接数据库,我们首先得有一个数据库

可以将数据库运行在本地,也可以运行在云端服务器上面

同时还可以使用docker来构建数据库方便管理

在这里我们就用docker来构建一个mysql数据库,数据库端口就是默认的3306

version: '3'
services:
    db:
        container_name: mysql
        image: mysql
        restart: always
        environment:
            - MYSQL_RANDOM_ROOT_PASSWORD=yes
            - MYSQL_DATABASE=demo
            - TZ=Asia/Shanghai
            - MYSQL_USER=demo
            - MYSQL_PASSWORD=123456789
        # 通过config/sql下面的sql脚本初始化数据库
        volumes:
            - ./config/sql:/docker-entrypoint-initdb.d/
        ports:
            - 3306:3306

这样我们的数据库就搭起来了,用户是demo,密码是123456789,同时我们通过config/sql文件夹下面的sql文件进行数据库的初始化

create table demo.users
{
    id int auto_increment,
    name varchar(32) not null,
    password varchar(255) not null,
    created_at  datetime,
    updated_at  datetime,
    deleted_at   datetime,
    primary key(id)
}

数据库连接

gorm中连接数据库是使用dsn字符串来连接

基本格式如下

dsn := "user:pass@tcp(127.0.0.1:3306)/dbname?charset=utf8mb4&parseTime=True&loc=Local"

user就是用户名,pass就是密码, dbname就是数据库的名字, charset就是字符集,parseTime是是否解析时间字符串,loc是地点

值得提一嘴的是mysql的utf8有两种一个是utf8mb3,一个是utf8mb4,其中mb3是阉割版,mb4才是完整的utf8

main.go

package main

import (
	"log"

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

func main() {
	dsn := "demo:123456789@tcp(127.0.0.1:3306)/demo?charset=utf8mb4&parseTime=True&loc=Local"
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
	if err != nil {
		log.Fatal(err)
		return
	}
	sqlDb, err := db.DB()
	if err != nil {
		log.Fatal(err)
		return
	}
	if err = sqlDb.Ping(); err != nil {
		log.Fatal(err)
		return
	}
}

到这里我们的数据库已经连接上了

声明模型

我们目前的模型只有一个User,所以我们需要声明这个结构体为数据库模型

type User struct {
	ID        uint `gorm:"primaryKey"`
	Name      string
	Password  string
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt gorm.DeletedAt
}

GORM 倾向于约定优于配置 默认情况下,GORM 使用 ID 作为主键,使用结构体名的 蛇形复数 作为表名,字段名的 蛇形 作为列名,并使用 CreatedAtUpdatedAt 字段追踪创建、更新时间。

DeletedAt是为了实现软删除而准备的。

增加一条记录我们需要先创建一个结构体的示例,将ID CreatedAt UpdatedAt DeletedAt留空

然后传入DB的创建函数, gorm会在数据库中创建一条记录,同时将ID CreatedAt UpdatedAt DeletedAt自动填充回示例中

user := User{
	Name:     "Mark",
	Password: "MarkMark",
}
db.Create(&user)

fmt.Println(user)
fmt.Println(user.ID)
fmt.Println(user.Name)
fmt.Println(user.Password)
fmt.Println(user.CreatedAt)
fmt.Println(user.UpdatedAt)
fmt.Println(user.DeletedAt)

结果如下

{1 Mark MarkMark 2023-08-13 15:41:26.822 +0800 CST 2023-08-13 15:41:26.822 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}}
1
Mark
MarkMark
2023-08-13 15:41:26.822 +0800 CST
2023-08-13 15:41:26.822 +0800 CST
{0001-01-01 00:00:00 +0000 UTC false}

可以看到原本没有填写的字段ID现在被写入1

user = User{ID: 1}
db.First(&user)

fmt.Println(user)
fmt.Println(user.ID)
fmt.Println(user.Name)
fmt.Println(user.Password)
fmt.Println(user.CreatedAt)
fmt.Println(user.UpdatedAt)
fmt.Println(user.DeletedAt)

我们重新给user赋一个User结构体的实例,这个示例里面只有一个ID字段,gorm会自动检测ID,然后根据ID进行查询,并且将内容赋值到user的每一个字段里

结果如下

{1 Mark MarkMark 2023-08-13 15:46:46 +0800 CST 2023-08-13 15:46:46 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}}
1
Mark
MarkMark
2023-08-13 15:46:46 +0800 CST
2023-08-13 15:46:46 +0800 CST
{0001-01-01 00:00:00 +0000 UTC false}

time.Sleep(time.Second * 5)
user = User{ID: 1}
db.First(&user)
user.Password = "MarkkraM"
db.Save(&user)

省略了打印代码 gorm中的Save会保存实例中的所有值,哪怕是默认值 所以比较好的做法是先查,将查询结果保存的实例中,然后修改实例, 然后通过Save修改值,同时gorm会同时更新UpdatedAt的值

结果如下

{1 Mark MarkkraM 2023-08-13 16:32:23 +0800 CST 2023-08-13 16:32:27.877 +0800 CST {0001-01-01 00:00:00 +0000 UTC false}}
1
Mark
MarkkraM
2023-08-13 16:32:23 +0800 CST
2023-08-13 16:32:27.877 +0800 CST
{0001-01-01 00:00:00 +0000 UTC false}

user = User{ID: 1}
db.Delete(&user)

gorm根据传入的实例的ID删除数据,由于我们设定了DeletedAt这个字段,所以删除后DeletedAt也有了数值。

结果如下

{1   0001-01-01 00:00:00 +0000 UTC 0001-01-01 00:00:00 +0000 UTC {2023-08-13 16:48:49.933 +0800 CST true}}
1


0001-01-01 00:00:00 +0000 UTC
0001-01-01 00:00:00 +0000 UTC
{2023-08-13 16:48:49.933 +0800 CST true}