Gorm | 青训营

139 阅读4分钟

[toc]

gorm快速入门使用

GORM简介

  • GORM(Go Object-Relational Mapping)是一个适用于 Go 语言的开源 ORM 库,用于简化数据库操作。它提供了一组丰富的功能,帮助开发人员在 Go 代码中进行数据库访问、查询和操作,而无需编写繁琐的 SQL 语句。
  • GORM的主要特性
    • 全功能 ORM
    • 关联 (Has One,Has Many,Belongs To,Many To Many,多态,单表继承)
    • Create,Save,Update,Delete,Find 中钩子方法
    • 支持 Preload、Joins 的预加载
    • 事务,嵌套事务,Save Point,Rollback To Saved Point
    • Context,预编译模式,DryRun 模式
    • 批量插入,FindInBatches,Find/Create with Map,使用 SQL 表达式、Context Valuer 进行 CRUD
    • SQL 构建器,Upsert,数据库锁,Optimizer/Index/Comment Hint,命名参数,子查询
    • 复合主键,索引,约束
    • Auto Migration
    • 自定义 Logger
    • 灵活的可扩展插件 API:Database Resolver(多数据库,读写分离)、Prometheus…
    • 每个特性都经过了测试的重重考验
    • 开发者友好

本次使用是以mysql为例子

1.安装对应的驱动

go get -u gorm.io/driver/mysql
go get -u gorm.io/gorm

2.连接数据库

连接不同的数据库需要导入相关的对应的数据的驱动程序,这里我使用的是Gorm中mysql驱动。

package main

import (
	"fmt"

	"gorm.io/gorm/schema"

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

var DB *gorm.DB

func init() {
	username := "root"  
	password := "123456" 
	host := "127.0.0.1" 
	port := 3306         
	Dbname := "db1"   
	dsn := fmt.Sprintf("%s:%s@tcp(%s:%d)/%s?charset=utf8&parseTime=True&loc=Local", username, password, host, port, Dbname)
	db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{
		Logger:                 logger.Default.LogMode(logger.Info),
		SkipDefaultTransaction: true, 
		NamingStrategy: schema.NamingStrategy{
			TablePrefix:         "",    
			SingularTable:       false, 
			NameReplacer:        nil,   
			NoLowerCase:         false, 
			IdentifierMaxLength: 0,
		},
	})
	if err != nil {
		panic("连接数据库失败, error=" + err.Error())
	}
	DB = db
}

通过上述操作进行初始化连接的操作

func main() {
	_ = DB.AutoMigrate(&Student{})
}

在通过此创建数据库

3.定义数据模型

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

gorm.Model

GORM 定义一个 gorm.Model 结构体,其包括字段 IDCreatedAtUpdatedAtDeletedAt

// gorm.Model 的定义
type Model struct{
ID         uint          `gorm:"primaryKey"`
CreatedAt  time.Time
UpdateAt   time.Time
DeletedAt  gorm.DeletedAt `gorm:"index"`
}

您可以将它嵌入到您的结构体中,以包含这几个字段 声明 model 时,tag 是可选的,GORM 支持以下 tag: tag 名大小写不敏感,但建议使用 camelCase 风格

标签名 说明 type 列数据类型,推荐使用兼容性好的通用类型,例如:所有数据库都支持 bool、int、uint、float、string、time、bytes 并且可以和其他标签一起使用,例如:not null、size, autoIncrement… 像 varbinary(8) 这样指定数据库数据类型也是支持的。在使用指定数据库数据类型时,它需要是完整的数据库数据类型,如:MEDIUMINT UNSIGNED not NULL AUTO_INSTREMENT size 指定列大小,例如:size:256 primaryKey 指定列为主键 unique 指定列为唯一 default 指定列的默认值 precision 指定列的精度 scale 指定列大小 not null 指定列为 NOT NULL autoIncrement 指定列为自动增长 embedded 嵌套字段 embeddedPrefix 嵌入字段的列名前缀 autoCreateTime 创建时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoCreateTime:nano autoUpdateTime 创建 / 更新时追踪当前时间,对于 int 字段,它会追踪时间戳秒数,您可以使用 nano/milli 来追踪纳秒、毫秒时间戳,例如:autoUpdateTime:milli index 根据参数创建索引,多个字段使用相同的名称则创建复合索引,查看 索引 获取详情 uniqueIndex 与 index 相同,但创建的是唯一索引

// 模型定义
type Student struct {
	ID      uint    `gorm:"size:10"`
	Name    string  `gorm:"size:16"`
	Age     int     `gorm:"size:3"`
	Email   *string `gorm:"size:128"`
	Type    string  `gorm:"column:_type;size:4"`
	Date    string  `gorm:"default:2022-12-30;comment:日期"`
	NewBing string  `gorm:"size:30;"`
}

type Student struct {
	Id     uint   `gorm:"size:3"`
	Name   string `gorm:"size:8"`
	Age    int    `gorm:"size:3"`
	Gender bool
	Email  *string `gorm:"size:32"`
}

4.实现增删改查操作

1).插入数据

func CreateInfo() {
	_ = dao.DB1.AutoMigrate(&Student{})
	email := "23322323@qq.com"
	s1 := Student{
		Name:   "中中",
		Age:    22,
		Gender: true,
		Email:  &email,
	}
	err := dao.DB1.Create(&s1).Error
	if err !=nil{
		log.Println("dao.Create is failed",err)
		return
	}
}

2).查询数据

func SelectOne() {
	var studentList []Student
	affected := dao.DB1.Find(&studentList).RowsAffected
	fmt.Println(affected)

	for _, i := range studentList {
		fmt.Println(i)
	}
	data, _ := json.Marshal(studentList)

	fmt.Println(string(data))

	studentList = []Student{}


	dao.DB1.Find(&studentList, "id > ?", 3)
	fmt.Println(studentList)
}

3).更新数据

func Update() {
	//save 单个记录全字段更新
	var student Student
	dao.DB1.Take(&student, 11)
	student.Name = "dqwe"
	student.Email = nil
	student.Age = 22
	//
	dao.DB1.Save(&student) 
	dao.DB1.Select("name").Save(&student) 

	var studentList []Student
	dao.DB1.Find(&studentList, "id > ?", 11).Update("gender", false)

	dao.DB1.Find(&studentList, []int{12, 13, 14}).Updates(Student{
		Age:    0,   // 使用结构体的话更新0值不会更改
		Gender: true,
	})
	// 使用map进行更新
	dao.DB1.Find(&studentList, []int{12, 13, 14}).Updates(map[string]any{
		"name": "fff123",
	})
}

4).删除数据

func Delete() {
	// 删除
	// 就一个delete
	dao.DB1.Delete(&Student{}, "name=?", "中中")
	// 进行多个数据删除
	var student Student
	dao.DB1.Take(&student, 11) // 先选择出多个数据
	dao.DB1.Delete(&student)
}

以上便是gorm快速入门教程。