首页 > 数据库 >Go语言gorm框架MySQL实践

Go语言gorm框架MySQL实践

时间:2023-08-13 11:00:57浏览次数:59  
标签:fmt drive Funtester Println id MySQL Go gorm

gorm是一个使用Go语言编写的ORM框架。文档齐全,对开发者友好,支持主流数据库。

我最近在补齐Go语言各类基础的框架和操作库的知识,终于进展到了数据库阶段,搜资料的时候基本都是推荐这个框架,可见其之流行程度。在不断尝试练习之后,总结了一些经验和使用方式,供初学者参考。

在之前使用Java语言的时候用过两种JDBC和mybatis,一种是本地操作数据库的一种是在Springboot项目中使用,两者使用习惯上都是基于MySQL语句,都是在操作层面把MySQL语句拼写完成。但是在gorm框架中几乎看不到完整的SQL语句,都是通过方法和参数

go.mod

github.com/jinzhu/gorm v1.9.16

在执行Go Mod Tidy的时候会把相关需要的依赖(这个用词可能不准)自动添加到mod文件中。

go.mod我现在也不是很熟悉,我也是抄能力发动+IDE提示完成的,通常来说比较顺利。

我的代码中依赖如下:

import (
	"fmt"
	"funtester/base"
	"funtester/futil"
	"github.com/jinzhu/gorm"
	_ "github.com/jinzhu/gorm/dialects/mysql"
	"log"
	"testing"
	"time"
)

初始化

这个演示Demo,内容偏基础,高阶的我也不会用,目前也用不到。演示分两类:初始化连接,初始化数据库。由于gorm自带了数据库初始化功能,会将Model对应数据库表创建(这个需要手动开启),所以这个在测试中还是比较常用的,如果辅以数据初始化的方法,基本满足我们日常开发测试服务的需求。

func init() {
	var err error
	drive, err = gorm.Open("mysql", "root:root123456@(localhost:3306)/funtester?charset=utf8&parseTime=true")
	if err != nil {
		fmt.Println(err)
		log.Fatalln("mysql conntect err")
	}
	drive.DB().SetMaxOpenConns(200)
	drive.DB().SetConnMaxLifetime(10 * time.Second)
	drive.DB().SetConnMaxIdleTime(10 * time.Second)
	drive.DB().SetMaxIdleConns(20)
	// 迁移 schema
	drive.AutoMigrate(&Funtester{})
	//注意: AutoMigrate 会创建表,缺少的外键,约束,列和索引,并且会更改现有列的类型(如果其大小、精度、是否为空可更改)。但 不会 删除未使用的列,以保护您的数据。
	//db.AutoMigrate(&User{}, &Product{}, &Order{})
	//drive.Set("gorm:table_options", "ENGINE=InnoDB").AutoMigrate(&Funtester{})//带参数的迁移

}

Model

type Funtester struct {
	gorm.Model
	Name string
	Age  int
}

这里分享一下MySQL数据库表结构:

DROP TABLE IF EXISTS `funtesters`;
CREATE TABLE `funtesters` (
  `id` int unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  `age` int unsigned DEFAULT NULL,
  `created_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `created_at` datetime DEFAULT NULL,
  `updated_at` datetime DEFAULT NULL,
  `deleted_at` datetime DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `idx_funtesters_deleted_at` (`deleted_at`)
) ENGINE=InnoDB AUTO_INCREMENT=241861 DEFAULT CHARSET=utf8mb3;

SET FOREIGN_KEY_CHECKS = 1;

这里应该就比较清晰看到gorm初始化数据库的时候的逻辑了。这里分享一下gorm.Model源码:

type Model struct {
	ID        uint `gorm:"primary_key"`
	CreatedAt time.Time
	UpdatedAt time.Time
	DeletedAt *time.Time `sql:"index"`
}

select

下面演示一下select常用语法,这里分成了两个:一个偏基础,一个偏复杂(主要是多查询条件串联)。这里可以很明显看出gorm拼接查询条件的思路,就是把查询条件分类然后单独写不同的条件,由gorm框架做SQL语句的拼接。

func TestSelect1(t *testing.T) {
	var f Funtester
	drive.First(&f, 34)//默认id
	last := drive.Last(&f, "age != 1")//添加条件
	fmt.Printf("查询到记录数 %d "+base.LINE, last.RowsAffected)
	fmt.Println(f)
	take := drive.Take(&f) //不指定顺序
	fmt.Println(take.RowsAffected)
}
// TestSelect2
// @Description: 常用查询和处理结果
// @param t
func TestSelect2(t *testing.T) {
	var fs []Funtester
	var f Funtester
	drive.Where("id = ?", 45).First(&f)//另外一种写法
	//fmt.Println(f)
	find := drive.Where("name like ?", "fun%").Find(&fs).Limit(10).Order("id")//多查询条件串联
	rows, _ := find.Rows()//获取结果
	defer rows.Close()
	for rows.Next() {
		var ff Funtester
		drive.ScanRows(rows, &ff)
		fmt.Println(ff.Age, ff.Name)
	}
	//另外一种写法
	var f1 Funtester
	drive.Where("name LIKE ?", "fun").Or("id = ?", 123).First(&f1)
	fmt.Println(f1)

}

update

有了select的基础,再来看update就比较容易了。

// TestUpdate
// @Description: 更新
// @param t
func TestUpdate(t *testing.T) {
	drive.Model(&Funtester{}).Where("id = ?", 241860).Update("name", base.FunTester+"3")
}

insert

gorm官文文档支持批量插入的,但是这个依赖包中并没有相关支持。各位如果使用跟我一样的依赖的话,

// TestInsert
// @Description: 增加
// @param t
func TestInsert(t *testing.T) {
	value := &Funtester{Name: "FunTester" + futil.RandomStr(10)}
	drive.Create(value)
	drive.Select("name", "age").Create(value) //只创建name和age字段的值
	futil.Sleep(1)
	drive.Omit("age", "name").Create(&Funtester{Name: "fds",Age: 122})   //过滤age和name字段创建
	fs := []Funtester{{Name: "fs" + futil.RandomStr(10), Age: 12}, {Name: "fs" + futil.RandomStr(10), Age: 12}}
	drive.Create(&fs)//这里不支持这么操作的
}

delete

删除操作跟以上两种操作使用方式一致。

func TestDelete(t *testing.T) {
	db := drive.Where("id = ?", 241859).Delete(&Funtester{})
	fmt.Println(db.RowsAffected)
}

执行SQL

当然gorm也是支持直接执行SQL语句的,有一个特殊就是执行查询语句的时候需要解析查询结果。

// TestSql
// @Description: 直接执行SQL
// @param t
func TestSql(t *testing.T) {
	var funtester []Funtester
	scan := drive.Raw("select * from funtesters where id > 333 limit 10").Scan(&funtester)
	fmt.Println(scan.RowsAffected)
	fmt.Println(funtester)
}

事务&回滚

在gorm高级语法的使用中,我觉得这个是非常实用的,对于一些测试语句的执行非常适合。

// TestRollBack
// @Description: 事务&回滚
// @param t
func TestRollBack(t *testing.T) {
	funtester := Funtester{Name: base.FunTester, Age: 32232}
	begin := drive.Begin()
	err := begin.Create(&funtester).Error
	if err != nil {
		begin.Rollback()
	}
	begin.Commit()

}

gorm的基本使用已经分享完了,下次分享使用gorm做性能测试的实践。

标签:fmt,drive,Funtester,Println,id,MySQL,Go,gorm
From: https://blog.51cto.com/FunTester/7065829

相关文章

  • 高性能MySQL 七-十六
    七、MySQL高级性能7.1分区表MySQL在创建表时使用PARTITIONBY子句定义每个分区存放的数据分区的一个主要目的是将数据按照一个较粗的力度分在不同的表中。这样做可以将相关的数据存放在一起1)分区表的原理SELECT查询:当查询一个分区表的时候,分区层先打开并锁住所有的底层表,......
  • 学习go语言编程之函数
    函数定义函数的基本组成:关键字func,函数名,参数列表,返回值,函数体,返回语句。示例如下:funcAdd(aint,bint)(retint,errerror){ ifa<0||b<0{ err=errors.New("shouldbenon-negativenumbers") return } returna+b,nil//支持多重返回值}如果参......
  • mysql在索引定义中直接使用条件语句
    原始数据库表如下:CREATETABLE`events`(`id`int(11)unsignedNOTNULLAUTO_INCREMENT,`status`enum('on','off')COLLATEutf8_unicode_ciNOTNULLCOMMENT'开关状态',`type`enum('gas_fee_free')COLLATEutf8_unicode_ciNOTNULL......
  • 8-12|go语言之输入
    在Go语言中,输入主要是通过标准库中的包来实现的。常用的包有`fmt`和`bufio`。以下是一些基本的Go输入方法:1.**使用`fmt.Scan()`和相关函数**:    `fmt.Scan()`,`fmt.Scanln()`,和`fmt.Scanf()`是用于从标准输入读取值的常用方法。    ```go  ......
  • Django实现文件上传、文件列表查看、修改、限流和日志记录
    Django实现文件上传、文件列表查看、修改、限流和日志记录本章先简单实现文件的上传,后续会将标题的功能一一添加上去实现,并且给出远程服务器的不同连接方式【密码和秘钥】,欢迎继续关注。安装了Django框架pipinstalldjango 创建一个Django项目django-adminstartproj......
  • 学习go语言编程之常量
    什么在常量在Golang中,常量是指在编译期就已知且不可改变的值。字面常量在程序中硬编码的常量值被称为字面常量,如:-12//整数类型常量3.1415926//浮点类型常量3.2+12i//复数类型常量true//布尔类型常量"foo"//字符串常量常量定义使用关键字con......
  • 学习go语言编程之数据类型
    数据类型概述Golang语言内置了如下基础数据类型:布尔类型:bool整型:int8,unit8,int16,uint16,int32,uint32,int64,uint64,int,uint,uintptr浮点类型:float32,float64复数类型:complex64,complex128字符串:string字符类型:rune错误类型:error同时,Golang还支持如下复合类型:指针:pointer数组......
  • 学习go语言编程之流程控制
    Golang支持如下4种流程控制语句:条件语句:if,else和elseif选择语句:switch,case和select循环语句:for,range跳转语句:goto条件语句示例代码:a:=3ifa<5{fmt.Println(a,"litterthan5")}else{fmt.Println(a,"notlitterthan5")}关于条件语句,要注意以下......
  • mysql8默认caching_sha2_password身份验证
    发生这个问题的原因是在mysql8.0以后,caching_sha2_password是默认的身份验证插件,而不是以往的mysql_native_password。在MySQLCommandLine工具下修改mysql的默认身份验证插件即可。Theserverrequestedauthenticationmethodunknowntotheclient[caching_sha2_passw......
  • Golang之旅——内存管理
    转载放在最前一文带你了解,虚拟内存、内存分页、分段、段页式内存管理[Golang三关-典藏版]一站式Golang内存洗髓经|Go技术论坛刘丹冰Aceld感谢以上文章作者,收获满满......