一篇文章简单了解gorm框架
什么是ORM
所谓ORM即是 Object Relational Mapping:对象关系映射,也就是说结构体 和 SQL数据库存在映射,这个时候就有了ORM语句
也就是说所谓ORM就是建立数据库中表数据与代码中结构体建立的关系
什么是gorm框架
GORM(Go Object Relational Mapping)是一个基于 Go 语言的 ORM 框架,用于简化数据访问和持久化的过程。它提供了一种简单、灵活和强大的方式来管理数据库,同时也支持多种数据库,如 MySQL、PostgreSQL、SQLite、SQL Server 等。
GORM 提供了一组易于使用的 API,可以通过结构体和标签来定义数据库表和字段,从而实现数据库的 CRUD 操作。它还支持事务、预加载、联表查询、分页查询、软删除、自动迁移和钩子等功能,以满足各种应用程序的需求。gorm是一个使用Go语言编写的ORM框架。它文档齐全,对开发者友好,支持主流数据库。
安装gorm
bash
go get -u gorm.io/gorm
go get -u gorm.io/driver/sqlite
连接数据库(以mysql为例子)
go
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"time"
)
func main() {
//dsn就是指定了数据库的一些配置,比如说访问数据库的用户,密码,以及库的名字编码方式等
dsn := "root:3356@tcp(127.0.0.1:3306)/minitok?charset=utf8mb4&parseTime=True&loc=Local"
db, err := gorm.Open(mysql.New(mysql.Config{
DSN: dsn, // DSN data source name//最为关键的一步,配置DSN
DefaultStringSize: 256, // string 类型字段的默认长度
DisableDatetimePrecision: true, // 禁用 datetime 精度,MySQL 5.6 之前的数据库不支持
DontSupportRenameIndex: true, // 重命名索引时采用删除并新建的方式,MySQL 5.7 之前的数据库和 MariaDB 不支持重命名索引
DontSupportRenameColumn: true, // 用 `change` 重命名列,MySQL 8 之前的数据库和 MariaDB 不支持重命名列
SkipInitializeWithVersion: false, // 根据当前 MySQL 版本自动配置
}), &gorm.Config{
SkipDefaultTransaction: false,
NamingStrategy: schema.NamingStrategy{
TablePrefix: "t_",
SingularTable: false,
},
DisableForeignKeyConstraintWhenMigrating: true,
})
fmt.Println(db, err)
}
实际上通过gorm连接数据库是十分简单的,最核心的一步是正确的配置DSN即可
在 GORM 中,DSN(Data Source Name)是一种用于连接数据库的字符串格式,包含了连接数据库所需的参数和信息。DSN 格式的具体内容会根据不同的数据库类型而有所不同,但通常包括以下信息:
- 数据库类型(如 MySQL、PostgreSQL、SQLite、SQL Server 等)
- 数据库用户名和密码
- 数据库地址和端口号
- 数据库名称
- 其他连接选项(如 SSL 选项等)
在 GORM 中,通过在 Open()
方法中传递 DSN 字符串,可以打开一个数据库连接。例如,在连接到 MySQL 数据库时,可以使用以下 DSN 格式:
go
"username:password@tcp(host:port)/database?charset=utf8&parseTime=True&loc=Local"
其中,username
和 password
分别为数据库的用户名和密码,host
和 port
分别为数据库的地址和端口号,database
为要连接的数据库名称。charset=utf8
表示使用 UTF-8 编码,parseTime=True
表示自动解析时间类型,loc=Local
表示使用本地时区。
在实际使用中,可以根据具体的数据库类型和需求来设置不同的 DSN 字符串。GORM 支持多种数据库,因此可以在不同的应用场景中灵活切换和使用。
此外,gorm定义了许多操作数据库的接口,比如db.create(&User{})
...等,可以自行查阅官方文档自行进行上手实践。
创建数据库:
在我们使用GROM
之前我们应该先创建好相应的数据库
sql
CREATE DATABASE db1
然后再使用GORM
连接操作数据库
go
package main
import (
"fmt"
"gorm.io/driver/mysql"
"gorm.io/gorm"
"gorm.io/gorm/schema"
"time"
)
// UserInfo 用户信息
type UserInfo struct {
ID uint
Name string
Gender string
Hobby string
}
func main() {
db, err := gorm.Open("mysql", "root:root1234@(127.0.0.1:13306)/db1?charset=utf8mb4&parseTime=True&loc=Local")
//DSN需要根据自己的配置进行更改
if err!= nil{
panic(err)
}
defer db.Close()
// 自动迁移
db.AutoMigrate(&UserInfo{})
u1 := UserInfo{2023, "Nanami", "女", "游戏"}
u2 := UserInfo{2024, "Sakana", "女", "游泳"}
// 创建记录
db.Create(&u1)
db.Create(&u2)
// 查询
var u = new(UserInfo)
db.First(u)
fmt.Printf("%#v\n", u)
var uu UserInfo
db.Find(&uu, "hobby=?", "足球")
fmt.Printf("%#v\n", uu)
// 更新
db.Model(&u).Update("hobby", "双色球")
// 删除
db.Delete(&u)
}
上述代码简单的演示了从连接数据库到对数据库进行简单的增删改查操作的过程;
更多的例子请查阅官方文档.
GORM Model
定义
在使用ORM
框架的时候,我们通常需要在代码中定义模型即Model
来与数据库中的表单进行映射 ,在GORM
框架中Models
通常是正常定义的结构体、基本的go类型或者它们的指针。
为了使定义数据库表单更加规范,GORM内置了一个gorm.Model
结构体。他的定义如下:
go
// gorm.Model 定义
type Model struct {
ID uint `gorm:"primary_key"`
CreatedAt time.Time
UpdatedAt time.Time
DeletedAt *time.Time
}
你可以把gorm.Model
匿名嵌入到自己的结构体之中
go
type BasicInfo struct {
Time time.Time `gorm:"column:basic_time"`
Basic_sentence string `gorm:"primaryKey"`
}
type User struct {
gorm.Model
infos BasicInfo `gorm:"embedded;embeddedPrefix:em_"`
Nickname string
Email *string
Age uint8
}
在调用db.AutoMigrate{&User{}}
之后再查询数据库之中的表单可以看到一下结果是符合我们预期的。
sql
mysql> describe t_users;
+----------------+---------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+----------------+---------------------+------+-----+---------+----------------+
| id | bigint(20) unsigned | NO | PRI | NULL | auto_increment |
| created_at | datetime | YES | | NULL | |
| updated_at | datetime | YES | | NULL | |
| deleted_at | datetime | YES | MUL | NULL | |
| basic_time | datetime | YES | | NULL | |
| basic_sentence | varchar(256) | NO | PRI | NULL | |
| nickname | varchar(256) | YES | | NULL | |
| email | varchar(256) | YES | | NULL | |
| age | tinyint(3) unsigned | YES | | NULL | |
+----------------+---------------------+------+-----+---------+----------------+
9 rows in set (0.00 sec)
顺带引入结构体标记(tags)的介绍
gorm:"column:xxx"
:指定数据库表中对应字段的名称。例如,gorm:"column:user_name"
表示将结构体字段映射到数据库表中的user_name
字段。gorm:"type:xxx"
:指定数据库字段的数据类型。例如,gorm:"type:int"
表示将结构体字段映射到数据库表中的int
类型字段。gorm:"size:xxx"
:指定数据库字段的长度或大小。例如,gorm:"size:255"
表示将结构体字段映射到数据库表中的长度为 255 的字段。gorm:"not null"
:指定数据库字段不能为空。例如,gorm:"not null"
表示将结构体字段映射到数据库表中的非空字段。gorm:"default:xxx"
:指定数据库字段的默认值。例如,gorm:"default:'unknown'"
表示将结构体字段映射到数据库表中的默认值为'unknown'
的字段。gorm:"unique"
:指定数据库字段的唯一性。例如,gorm:"unique"
表示将结构体字段映射到数据库表中的唯一字段。gorm:"index"
:指定数据库字段的索引。例如,gorm:"index"
表示将结构体字段映射到数据库表中的索引字段。gorm:"primary_key"
:指定数据库字段为主键。例如,gorm:"primary_key"
表示将结构体字段映射到数据库表中的主键字段。
GORM
中的CURD
CURD
通常指的是数据库的增删改查操作,本小节将系统地介绍如何使用GORM
来实现CURD操作,注:本文中db
变量全部默认为*gorm.DB
类型。
创建记录
首先定义相关Model
go
type User struct{
ID uint64 `gorm:"primaryKey"`
Name String `gorm:"default:'七海'"`
Age uint8
}
接着使用NewRecord(实例)
方法来判断检查给定的模型实例是否是一个新记录。
go
user1:=User{Name:"Nanami",Age: 19}
if db.NewRecord(user1){//若为新纪录则返回true
db.Create(&user1)//创建user1实例的新纪录
}
查找记录
一般查询
go
//用于保存返回结果
var user1 User
var users []User
db.First(&user1)//获取表中的第一条记录
db.Take(&user1)//随机获取一条数据
db.Last(&user1)//查找主键排序的最后一条记录
db,Find(&usres)//查找所有记录
使用Where
进行条件查找
go
db.Where("name=?","Nanami").Fisrt(&user1)
//等价于SELECT * FROM t_users WHERE name='Nanami' LIMIT 1(下面的语句也类似)
db.Where("name<>?","七海").find(&users)
db.Where("name IN (?)",[]string{"七海","Nanami"}).Find(&users)
db.Where("name=? AND age>=?","Nanami",20).Find(&users)
db.Where("created_at BETWEEN ? AND ?",last_Sunday,today).Find(&users)
更新数据库
go
db.First(&user1)
user1.Name="new_Nanami"
user1.age=100
db.save(&user1)
db.save()
方法会默认更新该对象的所有字段,即使你没有赋值
如果你只是想更新指定字段,那么你可以尝试使用Update
或者Updates
方法
go
db.Model(&user1).Update("name","Nakira")
//上述指令作用,修改user1的name字段值为"Nakira"
//需要注意的是name是在数据表中的列的名称,而不是结构体的名称,user1是数据库中的实例
db.Model(&uesr1).Where("active=?",true).Update("name","Nakira")
db.Model(&user2).Update(map[string]interface{}{"name":"Nanami","age":19,"active":false})
//使用map结构来实现更新多个属性
如果你想要忽略某些字段那么你可以考虑使用Select
,Omit
来实现
sql
db.Model(&user1).Select("name").Update(map[string]interface{}{"name":"Nanami","age":19,"active":false})//选中只更新name字段
db.Model(&user1).Omit("name").Update(map[string]interface{}{"name":"Nanami","age":19,"active":false})//忽略更新name字段
删除记录
Warning: 删除记录时候请确保主键不为空,`GROM`通过主键删除记录,如果主键为空,那么会删除该Model下的所有记录
g0
db.Delete(&user1)//删除现有记录
db.Where("name=?","Nanami").Delete(User{})//批量删除匹配的数据
本人初学gorm
,难免有错误之处,请各位多多指正、多多包涵。2023.7.28