# Gorm的使用
## Gorm是什么
- GORM 是 Go 语言的 ORM 库，提供模型定义、关联管理、事务支持、查询构建、数据迁移、钩子回调等功能，支持主流数据库（如 MySQL/PostgreSQL/SQLite），简化数据库操作。
## 如何使用Gorm
### 导入Gorm库
```go
import (
"gorm.io/driver/mysql"
)
```
### 连接数据库
```go
func main() {
// 初始化 Viper
viper.SetConfigName("config") // 配置文件名称（不带扩展名）
viper.SetConfigType("toml") // 配置文件类型
viper.AddConfigPath(".") // 配置文件路径
if err := viper.ReadInConfig(); err != nil {
log.Fatalf("Error reading config file: %v", err)
}
// 获取 database 配置
database := map[string]string{
"user": viper.GetString("mysql.user"),
"password": viper.GetString("mysql.password"),
"host": viper.GetString("mysql.host"),
"port": viper.GetString("mysql.port"),
"database": viper.GetString("mysql.database"),
}
// 打印 database 配置
fmt.Println("Database Config:", database)
// 构建 DSN（数据源名称）
dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",
database["user"],
database["password"],
database["host"],
database["port"],
database["database"],)
// 连接数据库
db, err := gorm.Open(mysql.Open(dsn), &gorm.Config{})
if err != nil {
log.Fatalf("Failed to connect to database: %v", err)
}
`````
### 数据库定义模型（表格）
- 在Gorm中，定义一张表使用的是结构体
	```go
type User struct {
	gorm.Model
	Name string
	Age int
}
	```
### 自动迁移表结构与创建表格
- 自动迁移表结构（方便我们修改表，给表添加参数），同时，如果没有该名字的表，Gorm则会创建他
```go
if err := db.AutoMigrate(&User{}); err != nil {
log.Fatalf("Failed to auto migrate: %v", err)
}
```
### CRUD操作
#### 创建数据
```go
//创建
user:=User{
	Name: "John",
	Age: 30,
}
if err := db.Create(&user).Error; err != nil {
	log.Fatalf("Failed to create user: %v", err)
}
fmt.Println("User created successfully!")
```
#### 查询数据
```go
//搜索数
//单一搜索
var user1,user2,user3 User
if err := db.First(&user1, 1).Error; err != nil {
	log.Fatalf("Failed to find user: %v", err)
}
user2.Name = "Jane"
if err=db.First(&user2).Error;err!=nil{
	log.Fatalf("Failed to find user: %v", err)
}
if err:=db.Where("name = ?", "Alice").First(&user3);err!=nil{
	log.Fatalf("Failed to find user: %v", err)
}
//查询多条记录
var users []User
if err:=db.Where("age > ?", 20).Find(&users);err!=nil{
	log.Fatalf("Failed to find users: %v", err)
}
// 查询时避免RecordNotFound错误
err := db.Where("name = ?", "Bob").First(&user).Error
if errors.Is(err, gorm.ErrRecordNotFound) {
	fmt.Println("User not found")
}
```
#### 更新记录
- update方式
```go
// 更新单个字段
db.Model(&user).Update("Age", 30)
// 更新多个字段（零值需使用map）
db.Model(&user).Updates(map[string]interface{}{"Age": 30, "Name": ""})
// 使用结构体更新（忽略零值）
db.Model(&user).Updates(User{Name: "Alice", Age: 0}) // Age不会被更新
```
- save方式
```
db.Save(&user) //更新所有字段
db.Save(&user).Omit("Name") //更新除Name字段外的所有字段
```
#### 删除记录
```go
db.Delete(&user) //软删除
db.Unscoped().Delete(&user) //直接强制删除
```